[ Pobierz całość w formacie PDF ]
Takie rozwiązanie może być przydatne w nieczęstych sytuacjach, w których występuje
konflikt nazw komponentów w bieżącej i nadrzędnej fabryce komponentów.
Element value służy do określania wartości prostych właściwości lub argumentów kon-
struktora. Jak już wspominano, niezbędnym krokiem jest konwersja wartości zródłowej
(która ma postać łańcucha) na odpowiedni typ docelowej właściwości lub argumentu kon-
struktora, czyli dowolny wbudowany typ skalarny, odpowiedni typ opakowania lub dowolny
inny typ, dla którego w kontenerze zarejestrowano implementację interfejsu PropertyPritor
zdolną do obsługi tego typu. Przeanalizujmy teraz konkretny przykład:
Powyższy fragment kodu ustawia właściwość typu String nazwaną classname i przypisuje
mu stałą wartość ch02.sample6.StaticDataWeatherDaoImpl; gdyby jednak właściwość
classname była typu java.lang.Class, fabryka komponentów musiałaby użyć wbudowanej
(i automatycznie rejestrowanej) implementacji interfejsu PropertyPritor (w tym przypadku kla-
sy ClassPritor) do konwersji tej wartości łańcuchowej na egzemplarz obiektu klasy Class.
Istnieje możliwość stosunkowo prostego rejestrowania własnych, niestandardowych im-
plementacji interfejsu PropertyPritor, które będą obsługiwały konwersję łańcuchów na
dowolne inne typy danych niezbędne do właściwej konfiguracji kontenera. Dobrym przykładem
106 Spring Framework. Profesjonalne tworzenie oprogramowania w Javie
sytuacji, w której takie rozwiązanie jest uzasadnione, jest przekazywanie łańcuchów repre-
zentujących daty, które mają być następnie wykorzystywane do ustawiania właściwości typu
Date. Ponieważ daty są szczególnie wrażliwe na uwarunkowania regionalne, użycie odpo-
wiedniej implementacji interfejsu PropertyPritor, która będzie prawidłowo obsługiwała
łańcuch zródłowy, jest najprostszym rozwiązaniem tego problemu. Sposób rejestrowania
niestandardowych implementacji tego interfejsu zostanie przedstawiony w dalszej części
tego rozdziału, przy okazji omawiania klasy CustomPritorConfigurer i postprocesora fa-
bryki komponentów. Niewielu programistów zdaje sobie sprawę z tego, że odpowiednie
mechanizmy interfejsu PropertyPritor automatycznie wykrywajÄ… i wykorzystujÄ… wszystkie
implementacje tego interfejsu, które należą do tego samego pakietu co klasa przeznaczona
do konwersji (jedynym warunkiem jest zgodność nazwy tej klasy z nazwą klasy implementują-
cej wspomniany interfejs, która dodatkowo musi zawierać sufiks Pritor). Oznacza to, że
w przypadku klasy MyType implementacja interfejsu PropertyPritor nazwana MyTypePritor
i należąca do tego samego pakietu co klasa MyType zostanie automatycznie wykryta i użyta
przez kod pomocniczy JavaBeans zdefiniowany w odpowiedniej bibliotece Javy (bez naj-
mniejszego udziału Springa).
Właściwości lub argumenty konstruktora, którym należy przypisać wartość null, wymagają
specjalnego traktowania, ponieważ pusty element value jest interpretowany jak łańcuch
pusty. Zamiast braku wartości należy więc użyć elementu null:
Element irref jest wygodnym sposobem wychwytywania błędów w odwołaniach do in-
nych komponentów za pośrednictwem wartości łańcuchowych reprezentujących ich nazwy.
Istnieje kilka komponentów pomocniczych samego Springa, które odwołują się do innych
komponentów (i wykonują za ich pomocą pewne działania) właśnie w formie wartości
swoich właściwości. Wartości tego rodzaju właściwości zwykle definiuje się w następujący
sposób:
Możliwie szybkie wykrywanie ewentualnych literówek w podobnych odwołaniach byłoby
oczywiście korzystne element irref w praktyce odpowiada właśnie za taką weryfikację.
Użycie elementu property w postaci:
umożliwia analizatorowi składniowemu XML udział we wczesnym procesie weryfikacji,
ponieważ już na etapie analizy składniowej można bez trudu wykryć odwołania do kompo-
nentów, które w rzeczywistości nie istnieją. Wartość wynikowa tej właściwości będzie do-
kładnie taka sama jak w przypadku użycia standardowego znacznika value.
Elementy list, set, map i props umożliwiają definiowanie i ustawianie złożonych właściwości
lub argumentów konstruktorów (odpowiednio typów java.util.List, java.util.Set,
java.util.Map i java.util.Properties). Przeanalizujmy teraz całkowicie nierzeczywisty
przykład, w którym definiowany komponent JavaBean będzie zawierał po jednej właściwości
każdego z wymienionych typów złożonych:
Rozdział 2. Fabryka komponentów i kontekst aplikacji 107
Kolekcje typu List, Map i Set mogą zawierać dowolne spośród wymienionych poniżej ele-
mentów:
(bean | ref | idref | list | set | map | props | value | null)
Jak pokazuje przedstawiony przykład listy, typy kolekcji mogą być dowolnie zagnieżdżane.
Warto jednak pamiętać, że właściwości lub argumenty konstruktorów otrzymujące na wejściu
typy kolekcji muszą być deklarowane za pomocą typów java.util.List, java.util.Set lub
java.util.Map. Nie możesz stosować innych typów kolekcji (np. ArrayList), nawet jeśli są
obsługiwane w Springu. Tego rodzaju ograniczenia mogą stanowić poważny problem, jeśli
musimy zapewnić wartość dla właściwości istniejącej klasy, która oczekuje określonego
108 Spring Framework. Profesjonalne tworzenie oprogramowania w Javie
typu w takim przypadku nie można konkretnego typu kolekcji zastąpić jego uniwersal-
nym odpowiednikiem. Jednym z rozwiązań jest użycie udostępnianych przez Springa po-
mocniczych komponentów fabrykujących (ang. factory beans): ListFactoryBean, SetFac-
toryBean lub MapFactoryBean. Za ich pomocą można swobodnie określać docelowy typ
kolekcji, w tym np. java.util.LinkerList. Więcej informacji na ten temat znajdziesz
w dokumentacji JavaDoc Springa. Same komponenty fabrykujące omówimy w dalszej części
rozdziału.
Ostatnim elementem, który może występować w roli wartości właściwości lub wartości ar-
gumentu konstruktora (lub wewnątrz któregoś z opisanych przed chwilą elementów kolekcji),
jest element bean. Oznacza to, że definicja komponentów może być de facto zagnieżdżana
w definicji innego komponentu (jako właściwość komponentu zewnętrznego). Przeanali-
[ Pobierz całość w formacie PDF ]