[ Pobierz całość w formacie PDF ]

elementy funkcjonalności są wspólne zarówno dla fabryki komponentów, jak i dla kon-
tekstu aplikacji.

Rozdział 2. Fabryka komponentów i kontekst aplikacji 95
W tym i w większości pozostałych rozdziałów tej książki analiza konfiguracji i funkcjonal-
ności kontenera będzie ilustrowana przykładami w wersji deklaratywnej, opartej na forma-
cie XML (w tym XmlBeanFactory lub ClassPathXmlApplicationContext) fabryki kompo-
nentów i kontekstu aplikacji. Warto zdać sobie sprawę z tego, że funkcjonalność kontenera
w żadnym razie nie jest tożsama z formatem jego konfiguracji. Konfiguracja oparta na
XML jest co prawda wykorzystywana przez zdecydowaną większość użytkowników Springa,
jednak istnieje też kompletny interfejs API dla mechanizmów konfiguracji i dostępu do
kontenerów, w tym obsługa innych formatów konfiguracji (które mogą być konstruowane
i obsługiwane w bardzo podobny sposób jak odpowiednie dokumenty XML). Przykładowo,
istnieje klasa PropertiesBeanDefinitionRearer, która odpowiada za załadowanie do fabryki
komponentów definicji zapisanych w plikach właściwości Javy.
Uruchamianie kontenera
Poprzednie przykłady pokazały, jak można programowo uruchamiać kontener z poziomu
kodu użytkownika. W tym punkcie przeanalizujemy kilka ciekawych rozwiązań w tym zakresie.
Egzemplarz (implementację) interfejsu ApplicationContext można wczytać, wskazując
ścieżkę do odpowiedniej klasy (pliku):
ApplicationContext appContext =
new ClassPathXmlApplicationContext("ch03/sample2/applicationContext.xml");
// Uwaga: ApplicationContext jest egzemplarzem BeanFactory, to oczywiste!
BeanFactory factory = (BeanFactory) appContext;
Można też wskazać konkretną lokalizację w systemie plików:
ApplicationContext appContext =
new FileSystemXmlApplicationContext("/some/file/path/applicationContext.xml");
Istnieje też możliwość łączenia dwóch lub większej liczby fragmentów prezentowanych już
dokumentów XML. Takie rozwiązanie umożliwia nam lokalizowanie definicji komponen-
tów w ramach logicznych modułów, do których należą, i jednocześnie tworzenie jednego
kontekstu na bazie połączonych definicji. Przykład prezentowany w następnym rozdziale
pokaże, że opisane podejście może być bardzo użyteczne także podczas testów. Poniżej
przedstawiono jeden z wcześniejszych przykładów konfiguracji, tyle że tym razem złożony
z dwóch fragmentów kodu XML:
applicationContext-dao.xml:
"http://www.springframework.org/dtd/spring-beans.dtd"
96 Spring Framework. Profesjonalne tworzenie oprogramowania w Javie
applicationContext-services.xml:
"http://www.springframework.org/dtd/spring-beans.dtd"
Uważni Czytelnicy zapewne zauważyli, że w porównaniu z wcześniejszymi przykłada-
mi nieznacznie zmieniono sposób odwoływania się do komponentu weatherDao, który
wykorzystujemy jako właściwość komponentu usługi pogodowej; odwołania do kom-
ponentów szczegółowo omówimy w dalszej części rozdziału.
Aby wczytać i połączyć oba fragmenty (teoretycznie może ich być więcej), musimy je tylko
wymienić w tablicy nazw (łańcuchów) przekazywanej do konstruktora klasy ClassPathXml-
ApplicationContext:
ApplicationContext appContext = new ClassPathXmlApplicationContext(
new String[] {"applicationContext-services.xml",
"applicationContext-dao.xml"});
Abstrakcja Resource Springa (którą szczegółowo omówimy nieco pózniej) umożliwia sto-
sowanie prefiksu classpath*: do wyszczególniania tych wszystkich zasobów pasujących
do konkretnej nazwy, które są widoczne z perspektywy classloadera i jego classloaderów
nadrzędnych. Przykładowo, gdyby nasza aplikacja została rozproszona pomiędzy wiele pli-
ków JAR, wszystkich należących do ścieżki do klas, z których każdy zawierałby własny
fragment kontekstu aplikacji nazwany applicationContext.xml, moglibyśmy w prosty spo-
sób określić, że chcemy utworzyć kontekst złożony ze wszystkich istniejących fragmentów:
ApplicationContext appContext =
new ClassPathXmlApplicationContext("classpath*:applicationContext.xml"});
Okazuje się, że tworzenie i wczytywanie fabryki komponentów skonfigurowanych za po-
mocą odpowiednich zapisów języka XML jest bardzo łatwe. Najprostszym rozwiązaniem
jest użycie abstrakcji Resource Springa, która umożliwia uzyskiwanie dostępu do zasobów
według ścieżki klas:
ClassPathResource res =
new ClassPathResource("org/springframework/prospering/beans.xml"});
XmlBeanFactory factory = new XmlBeanFactory(res);
lub:
FilesystemResource res = new FilesystemResource("/some/file/path/beans.xml");
XmlBeanFactory factory = new XmlBeanFactory(res);

Rozdział 2. Fabryka komponentów i kontekst aplikacji 97
Równie dobrze moglibyśmy użyć egzemplarza InputStream:
InputStream is = new FileInputStream("/some/file/path/beans.xml");
XmlBeanFactory factory = new XmlBeanFactory(is);
Aby wyczerpać ten temat, musimy wspomnieć o możliwości prostego oddzielenia operacji
tworzenia fabryki komponentów od procesu przetwarzania definicji komponentów. Nie bę-
dziemy się zajmować tym zagadnieniem w szczegółach, warto jednak pamiętać, że takie
wyodrębnienie zachowania fabryki komponentów od mechanizmów przetwarzania definicji
komponentów upraszcza stosowanie innych formatów konfiguracji:
ClassPathResource res = new ClassPathResource("beans.xml"});
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
reader.loadBeanDefinitions(res);
Stosując klasę GenericApplicationContext dla kontekstu aplikacji, możemy w podobny
sposób oddzielić kod tworzący ten kontekst od kodu przetwarzającego definicje kompo-
nentów. Wiele aplikacji Springa w ogóle nie tworzy kontenera programowo, ponieważ bazuje
na odpowiednim kodzie tego frameworka (który wykonuje odpowiednie działania w ich
imieniu). Przykładowo, możemy deklaratywnie skonfigurować mechanizm ContextLoarer
Springa w taki sposób, aby automatycznie wczytywał kontekst aplikacji w momencie [ Pobierz całość w formacie PDF ]
  • zanotowane.pl
  • doc.pisz.pl
  • pdf.pisz.pl
  • akte20.pev.pl