w ,

FajneFajne Dobre!Dobre! ŚwietnieŚwietnie Że co?Że co? WnerwWnerw SmuteczekSmuteczek

Spring Context – Jak Działa Kontener IoC?

Schemat działania Spring Context

Podstawowym komponentem w Spring Framework jest kontener IoC. W Springu ma on swoją nazwę – Spring Context. Jego dobre zrozumienie jest niezbędne do tworzenia aplikacji, dlatego w tym artykule:

  • przybliżę Ci czym jest kontener IoC,
  • pokażę różne implantacje kontekstu Springa,
  • wytłumaczę hierarchiczna strukturę Spring Context.

Czym jest Kontener IoC?

Kontener IoC pozwala na przechowywanie obiektów i zarządzanie nimi w całym cyklu życia aplikacji. Podejście to jest wykorzystywane przez wiele frameworków – nie tylko w Springu. Największe korzyści płynące z jego stosowania to:

  • nie musisz ręcznie tworzyć obiektów, kontener zrobi to za Ciebie,
  • umożliwia wstrzykiwanie zależności – czyli dostarczanie obiektu dokładnie tam gdzie tego potrzebujesz.

Działanie kontenerów IoC w Spring

Pierwszym i najważniejszym Kontenerem IoC działającym pod kontrolą Spring jest BeanFactory. BeanFactory to nic innego jak wzorzec fabryka wykorzystany na potrzeby kontenera IoC.

Wynikiem działania BeanFactory jest Bean, czyli obiekt zarządzany przez kontener IoC.

spring bean factory

W pierwszej kolejności musimy dostarczyć konfiguracje – czyli informacji na temat jak mają być tworzone beany, oraz jak mają się one zachowywać. Konfiguracje możemy dostarczyć na 3 sposoby:

  • Adnotacje – oznaczenie klas adnotacjami, dzięki którym Spring wie jak dany bean ma zostać zakwalifikowany.
  • Klasa konfiguracyjna – miejsce w którym dostarczamy definicję beanów za pomocą kodu źródłowego (np. Java, Kotlin).
  • Plik XML – ustrukturyzowany plik, który zawiera definicje beanów ujętą w znacznikach XML.

Najczęściej stosuje się podejście wykorzystujące adnotacje. Natomiast w przypadku kiedy nie mamy możliwości ingerencji w kod (klasa pochodzi z zewnętrznej biblioteki) wówczas stosowane jest podejście drugie. Niemniej wykorzystywanie XML do definiowania beanów to już podejście zapomniane i raczej uświadczymy je w starszych aplikacjach (legacy).

W drugiej kolejności dostarczana jest klasa, której cykl życia ma być zarządzany przez Spring Context.

Implementacje kontenerów

Oprócz BeanFactory możemy wybrać inny kontener – jest nim ApplicationContext. Należy pamiętać, że ApplicationContext jest interfejsem rozszerzającym BeanFactory, czyli dostarcza dokładnie te same możliwości a dodatkowo:

  • Zestaw metod umożliwiających na swobodny do beanów.
  • Proste wczytywanie zasobów aplikacji.
  • Możliwość publikowania zdarzeń i nasłuchiwania zdarzeń.
  • Wsparcie dla dostarczania konfiguracji na potrzeby internacjonalizacji.
Feature Bean Factory Application Context
Zarządzanie beanami
Wsparcie adnotacji
Obsługa zdarzeń
Obsługa MessageSource na potrzeby i18n
Obsługa transakcji i AOP
Wsparcie BeanFactoryPostProcessor
(zarządzanie konfiguracją Beana w trakcie życia aplikacji)

Pytanie, który wybrać?
Zalecane jest stosowanie ApplicationContext, ze względu na jego szersze możliwości. BeanFactory sprawdzi się jedynie w rozwiązaniach, gdzie musimy liczyć każdy kilobajt i oszczędzać zasoby sprzętowe.

WebApplicationContext a Spring Context

WebApplicationContext to kolejny kontekst Springa, który implementuje ApplicationContext. Przede wszystkim zawiera on konfiguracje dostosowaną specjalnie na potrzeby obsługi warstwy webowej. Dlatego jest zamiennie nazywany ServletContext. Ponadto jego głównym założeniem jest przechowywanie beanów odpowiedzialnych za obsługę żądań webowych.

Pojedyncza aplikacja webowa może mieć kilka ServletContext’ów. W Spring Boot domyślnie jest jeden. Jednak dopuszczalne jest skonfigurować ich więcej – np. oddzielny dla dostarcza statycznych plików, oddzielny dla serwowania API.

W praktyce bardzo rzadko wykorzystuje się więcej niż jeden ServletContext, zwłaszcza w dobie mikroserwisów.

Hierarchia kontekstów w Spring

Posiadając w aplikacji wiele kontekstów trzeba mieć na uwadze zależność pomiędzy nimi występującą.

Jeśli w aplikacji jest więcej niż jeden ServletContext, to trzeba pamiętać, że Beany w nich skonfigurowane nie są wdzialne/dostępne pomiędzy innymi ServletContext’ami. Natomiast każdy z kontekstów ma dostęp do tzw. Root Context (może być to BeanFactory lub ApplicationContext).

Przede wszystkim w Root Context definiowane są beany odpowiedzialne za dostęp do bazy danych, za serwisy – i są one dostępne dla każdego kontekstu.

W ServletContext definiowane są:

  • Kontrolery
  • ViewResolver (mapuje nazwy widoków na konkretne pliki)
  • HandlerMapping (odpowiedzialny za obsługę żądań)

Przykładowo jeśli zdefiniujemy w ServletContext1 kontroler, to ten kontroler będzie widzialny jednie w tym kontekście. ServletContext2 nie będzie miał już do niego dostępu. Natomiast ServletContext1 i ServletContext2 będą miały dostęp do wszystkich beanów zdefiniowanych w ApplicationContext.

spring context hierarchy

Spring Context w Spring Boot

Warto mieć na uwadze, ze Spring Boot dostarcza nam automatyczną konfiguracje i implementacje dla kontekstów. Na przykład tworząc aplikację bez żadnych zależności webowych (pakiet spring-boot-starter) otrzymamy implementację ApplicationContext. Natomiast w przypadku kiedy dodamy zależność do Web’a (pakiet spring-boot-starter-web) to Spring Boot automatycznie skonfiguruje dla nas WebApplicationContext – który zgodnie z tym co wyżej opisałem zawiera wszystkie funkcjonalności ApplicationContext, a oprócz tego dostarcza nowe.

Zobacz mój wykład Spring IoC Containers

Na moim kanale YouTube znajdziesz wykład Cała Prawda o Spring IoC Containers w ramach którego przedstawiłem działanie kontenerów. Ponadto jest to jeden z materiałów, który udostępniłem publicznie z mojego zbioru kursów pochodzących z AkademiaSpring.pl

Schemat działania Spring Context

Źródła

  • https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#spring-core
  • https://docs.spring.io/spring-framework/docs/5.0.0.RC3/spring-framework-reference/web.html#spring-web
  • https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/context/WebApplicationContext.html
  • https://www.logicbig.com/tutorials/spring-framework/spring-web-mvc/application-scope.html

Pytania rekrutacyjne ze Spring Context

  1. Czym jest Spring Context?
  2. Jakie są implementacje Spring Contextu, czym one się różnią?
  3. Jak działa hierarchia kontekstów w Springu?
  4. Różnica pomiędzy zasięgiem beanów singleton a application?
  5. Czym jest WebApplicationContext?

Napisane przez Przemysław Bykowski

Aktywny programista i energiczny trener. Specjalizuje się w Spring Boot i uczę go w ramach AkademiaSpring.pl. Po godzinach udzielam się na YouTubach. Więcej o mnie.

Dodaj komentarz

Spring - solidny start

Spring i Spring Boot – rzeczowy przewodnik

REST API – Efektywna Droga Do Zrozumienia