Uczę się Spring Framework, który jest używany w moim projekcie. Znalazłem wpis ContextLoaderListener w moim pliku web.xml . Ale nie możesz dowiedzieć się, jak dokładnie pomaga to deweloperowi?
W oficjalnej dokumentacji ContextLoaderListener jest napisane, że należy uruchomić WebApplicationContext . Dotyczące WebApplicationContext Javadocs powiedzieć:
Interfejs umożliwiający konfigurację aplikacji internetowej.
Ale nie jestem w stanie zrozumieć, co mam na osiągnięcie z ContextLoaderListener który wewnętrznie inicjuje WebApplicationContext ?
Zgodnie z moim rozumieniem , ContextLoaderListener odczytuje plik konfiguracyjny Springa (z wartością podaną w kontekście contextConfigLocation w web.xml ), analizuje go i ładuje pojedynczy komponent bean zdefiniowany w tym pliku konfiguracyjnym. Podobnie, gdy chcemy załadować prototypowy bean , użyjemy tego samego kontekstu aplikacji internetowej, aby go załadować. Tak więc inicjalizujemy aplikację internetową za pomocą ContextLoaderListener , abyśmy z wyprzedzeniem przeczytali / przeanalizowali / zweryfikowali plik konfiguracyjny i za każdym razem, gdy chcemy wprowadzić zależność, możemy od razu to zrobić bez żadnych opóźnień. Czy to rozumienie jest prawidłowe?
źródło
Odpowiedzi:
Twoje rozumienie jest prawidłowe.
ApplicationContext
Jest, gdy fasola Wiosna żyć. CelContextLoaderListener
jest dwojaki:aby powiązać cykl życia z
ApplicationContext
cyklem życiaServletContext
izautomatyzować tworzenie
ApplicationContext
pliku, więc nie musisz pisać jawnego kodu, aby go utworzyć - jest to wygodna funkcja.Inną wygodną rzeczą
ContextLoaderListener
jest to, że tworzyWebApplicationContext
iWebApplicationContext
zapewnia dostęp do fasoliServletContext
viaServletContextAware
igetServletContext
metody.źródło
WebApplicationContext
. W przeciwnym razie musiałby zostać utworzony ręcznie.ContextLoaderListener
implementuje metodę niszczenia, aby zniszczyć wszystkie ziarna po wyłączeniu kontenera WWW?contextDestroyed
jest wezwany. Zobacz dokumentację API.web.xml
. W moim pliku xml znajdują się dwa odbiornikiContextLoaderListener
iDispatcherServlet
. Więc myślę, że nie ma potrzeby obu, czy można bezpiecznie usunąć,ContextLoaderListener
dlaczego pytam, ponieważ aplikacja działa od 7-8 miesięcy. web.xml jest tutaj w celach informacyjnych.ContextLoaderListener
jest opcjonalne . Dla przypomnienia: możesz uruchomić aplikację Spring bez konfigurowaniaContextLoaderListener
, wystarczy podstawowe minimum zaweb.xml
pomocąDispatcherServlet
.Oto jak by to wyglądało:
web.xml
Utwórz plik o nazwie
dispatcher-servlet.xml
i zapisz go podWEB-INF
. Ponieważ wspomnieliśmyindex.jsp
na liście powitalnej, dodaj ten plik podWEB-INF
.dispatcher-servlet.xml
W
dispatcher-servlet.xml
określ swoje fasole:źródło
W przypadku prostej aplikacji Spring nie musisz definiować
ContextLoaderListener
w swoimweb.xml
; możesz po prostu umieścić wszystkie pliki konfiguracyjne Springa w<servlet>
:W przypadku bardziej złożonej aplikacji Spring, w której jest wiele
DispatcherServlet
zdefiniowanych, możesz mieć wspólne pliki konfiguracyjne Spring, które są współdzielone przez wszystkieDispatcherServlet
zdefiniowane wContextLoaderListener
:Pamiętaj tylko, że
ContextLoaderListener
wykonuje rzeczywistą pracę inicjalizacyjną dla kontekstu aplikacji głównej .Zauważyłem, że ten artykuł bardzo pomaga: Spring MVC - Kontekst aplikacji a kontekst aplikacji internetowej
źródło
Blog „ Cel użycia ContextLoaderListener - Spring MVC ” zawiera bardzo dobre wyjaśnienie.
Zgodnie z nią konteksty aplikacji są hierarchiczne, a zatem kontekst DispatcherSerlvet staje się elementem potomnym kontekstu ContextLoaderListener. Dzięki temu technologia zastosowana w warstwie kontrolera (Struts lub Spring MVC) może być niezależna od tworzonego kontekstu głównego ContextLoaderListener.
źródło
Jeśli chcesz umieścić plik serwletu w niestandardowej lokalizacji lub z niestandardową nazwą zamiast domyślnej konwencji nazewnictwa
[servletname]-servlet.xml
i ścieżkiWeb-INF/
, możesz użyćContextLoaderListener
.źródło
ContextLoaderListner to nasłuchiwacz serwletów, który ładuje wszystkie różne pliki konfiguracyjne (konfiguracja warstwy usług, konfiguracja warstwy trwałości itp.) Do jednego kontekstu aplikacji sprężynowej.
Pomaga to podzielić konfiguracje sprężyn na wiele plików XML.
Po załadowaniu plików kontekstowych Spring tworzy obiekt WebApplicationContext w oparciu o definicję fasoli i przechowuje go w ServletContext Twojej aplikacji internetowej.
źródło
Ten odbiornik Bootstrap ma uruchamiać i zamykać WebApplicationContext roota Springa . Ponieważ aplikacja internetowa może mieć wiele serwletów rozsyłających, a każdy z nich ma swój własny kontekst aplikacji zawierający kontrolery, program rozpoznawania widoku, mapowania programów obsługi itp. Ale możesz chcieć mieć komponenty bean usługi, komponenty bean DAO w kontekście aplikacji root i chcieć używać ich we wszystkich kontekstach aplikacji potomnych ( kontekst aplikacji utworzony przez serwlety dyspozytorskie).
Drugie zastosowanie tego słuchacza jest wtedy, gdy chcesz użyć zabezpieczenia sprężynowego.
źródło
Konteksty root i child Zanim zaczniesz czytać dalej, zrozum, że -
Wiosna może mieć jednocześnie wiele kontekstów. Jeden z nich będzie kontekstem głównym, a wszystkie inne konteksty będą kontekstami potomnymi.
Wszystkie konteksty potomne mają dostęp do komponentów bean zdefiniowanych w kontekście głównym; ale przeciwieństwo nie jest prawdą. Kontekst główny nie może uzyskać dostępu do komponentów bean kontekstów potomnych.
ApplicationContext:
applicationContext.xml to konfiguracja kontekstu głównego dla każdej aplikacji internetowej. Spring ładuje plik applicationContext.xml i tworzy ApplicationContext dla całej aplikacji. W każdej aplikacji internetowej będzie tylko jeden kontekst aplikacji. Jeśli nie zadeklarujesz jawnie nazwy pliku konfiguracji kontekstu w web.xml przy użyciu parametru contextConfigLocation, Spring wyszuka plik applicationContext.xml w folderze WEB-INF i wyrzuci wyjątek FileNotFoundException, jeśli nie może znaleźć tego pliku.
ContextLoaderListener Wykonuje rzeczywistą pracę inicjalizacyjną dla kontekstu aplikacji głównej. Odczytuje parametr kontekstu „contextConfigLocation” i przekazuje jego wartość do instancji kontekstu, analizując je na potencjalnie wiele ścieżek plików, które można oddzielić dowolną liczbą przecinków i spacji, np. „WEB-INF / applicationContext1.xml, WEB-INF / applicationContext2.xml ”. ContextLoaderListener jest opcjonalne. Dla przypomnienia: możesz uruchomić aplikację Spring bez konfigurowania ContextLoaderListener, wystarczy podstawowy minimalny plik web.xml z DispatcherServlet.
DispatcherServlet DispatcherServlet jest zasadniczo serwletem (stanowi rozszerzenie HttpServlet), którego głównym celem jest obsługa przychodzących żądań WWW zgodnych ze skonfigurowanym wzorcem adresu URL. Przyjmuje przychodzący identyfikator URI i znajduje właściwą kombinację kontrolera i widoku. Więc to jest przedni kontroler.
Podczas definiowania DispatcherServlet w konfiguracji sprężynowej, udostępniasz plik XML z wpisami klas kontrolerów, odwzorowaniami widoków itp. Za pomocą atrybutu contextConfigLocation.
WebApplicationContext Oprócz ApplicationContext w jednej aplikacji internetowej może istnieć wiele elementów WebApplicationContext. Krótko mówiąc, każdy DispatcherServlet powiązany z pojedynczym WebApplicationContext. Plik xxx-servlet.xml jest specyficzny dla serwletu DispatcherServlet, a aplikacja internetowa może mieć więcej niż jeden serwlet DispatcherServlet skonfigurowany do obsługi żądań. W takich scenariuszach każdy DispatcherServlet miałby skonfigurowany oddzielny xxx-servlet.xml. Jednak plik applicationContext.xml będzie wspólny dla wszystkich plików konfiguracyjnych serwletu. Spring domyślnie wczyta plik o nazwie „xxx-servlet.xml” z folderu WEB-INF aplikacji webowych, gdzie xxx to nazwa serwletu w web.xml. Jeśli chcesz zmienić nazwę tej nazwy pliku lub zmienić lokalizację, dodaj parametr inicjacji z wartością contextConfigLocation jako nazwę parametru.
Porównanie i relacja między nimi:
ContextLoaderListener vs DispatcherServlet
ContextLoaderListener tworzy kontekst aplikacji głównej. Pozycje DispatcherServlet tworzą jeden kontekst aplikacji podrzędnej dla każdego wpisu serwletu. Konteksty potomne mogą uzyskiwać dostęp do komponentów bean zdefiniowanych w kontekście głównym. Fasola w kontekście głównym nie może uzyskać dostępu do fasoli w kontekstach potomnych (bezpośrednio). Wszystkie konteksty są dodawane do ServletContext. Dostęp do kontekstu głównego można uzyskać za pomocą klasy WebApplicationContextUtils.
Po przeczytaniu dokumentacji Spring, rozumiem:
a) Konteksty aplikacji są hierarchiczne, podobnie jak WebApplicationContexts. Zapoznaj się z dokumentacją tutaj.
b) ContextLoaderListener tworzy główny kontekst aplikacji internetowej dla aplikacji internetowej i umieszcza go w ServletContext. Ten kontekst może być używany do ładowania i rozładowywania ziaren sterowanych sprężynami w zależności od technologii używanej w warstwie kontrolera (Struts lub Spring MVC).
c) DispatcherServlet tworzy swój własny WebApplicationContext, a programy obsługi / kontrolery / programy rozpoznające widok są zarządzane przez ten kontekst.
d) Gdy ContextLoaderListener jest używany w tandemie z DispatcherServlet, najpierw tworzony jest główny kontekst aplikacji WWW, jak wspomniano wcześniej, a także jest tworzony przez DispatcherSerlvet kontekst potomny i dołączany do głównego kontekstu aplikacji. Zapoznaj się z dokumentacją tutaj.
Kiedy pracujemy z Spring MVC i używamy Springa również w warstwie usług, udostępniamy dwa konteksty aplikacji. Pierwsza jest konfigurowana za pomocą ContextLoaderListener, a druga za pomocą DispatcherServlet
Ogólnie rzecz biorąc, zdefiniujesz wszystkie komponenty bean powiązane z MVC (kontroler i widoki itp.) W kontekście DispatcherServlet, a wszystkie komponenty bean przekrojowe, takie jak bezpieczeństwo, transakcje, usługi itp. W kontekście głównym, za pomocą ContextLoaderListener.
Więcej informacji znajdziesz tutaj: https://siddharthnawani.blogspot.com/2019/10/contextloaderlistener-vs.html
źródło
Zasadniczo możesz izolować kontekst aplikacji głównej i kontekst aplikacji internetowej za pomocą ContextLoaderListner.
Plik konfiguracyjny mapowany z parametrem kontekstu będzie zachowywał się jak konfiguracja kontekstu aplikacji głównej. Plik konfiguracyjny odwzorowany za pomocą serwletu dyspozytorskiego będzie zachowywał się jak kontekst aplikacji internetowej.
W dowolnej aplikacji internetowej możemy mieć wiele serwletów dyspozytorskich, a więc wiele kontekstów aplikacji internetowych.
Ale w każdej aplikacji internetowej możemy mieć tylko jeden główny kontekst aplikacji, który jest współdzielony ze wszystkimi kontekstami aplikacji internetowych.
Powinniśmy zdefiniować nasze wspólne usługi, jednostki, aspekty itp. W kontekście aplikacji root. Kontrolery, przechwytywacze itp. Są w odpowiednim kontekście aplikacji internetowej.
Przykładowy plik web.xml to
Tutaj klasa config example.config.AppConfig może być używana do konfigurowania usług, jednostek, aspektów itp. W kontekście aplikacji głównej, które będą współdzielone ze wszystkimi innymi kontekstami aplikacji internetowych (na przykład tutaj mamy dwie klasy konfiguracji kontekstu aplikacji internetowej RestConfig i WebConfig)
PS: Tutaj ContextLoaderListener jest całkowicie opcjonalny. Jeśli nie wspomnimy tutaj o ContextLoaderListener w web.xml, AppConfig nie będzie działać. W takim przypadku musimy skonfigurować wszystkie nasze usługi i jednostki w konsoli WebConfig i Rest Config.
źródło
Daje ci punkt zaczepienia, aby umieścić kod, który chcesz wykonać w czasie wdrażania aplikacji internetowej
źródło
Klasa Listener - nasłuchuje zdarzenia (np. Uruchomienie / zamknięcie serwera)
ContextLoaderListener -
Pliki konfiguracyjne mogą być dostarczane w ten sposób w pliku web.xml
źródło
W kontekście Spring Framework celem ContextLoaderListener jest załadowanie innych komponentów bean w aplikacji, takich jak komponenty warstwy środkowej i warstwy danych, które sterują zapleczem aplikacji.
źródło
Twoje rozumienie jest prawidłowe. Zastanawiam się, dlaczego nie widzisz żadnych zalet w ContextLoaderListener. Na przykład musisz zbudować fabrykę sesji (aby zarządzać bazą danych). Ta operacja może zająć trochę czasu, więc lepiej zrobić to podczas uruchamiania. Oczywiście możesz to zrobić za pomocą serwletów init lub czegoś innego, ale zaletą podejścia Springa jest to, że konfigurujesz bez pisania kodu.
źródło
Jeśli napiszemy web.xml bez ContextLoaderListener, nie możemy zapewnić atestacji przy użyciu customAuthenticationProvider w wiosennych zabezpieczeniach. Ponieważ DispatcherServelet jest kontekstem podrzędnym ContextLoaderListener, customAuthenticationProvider jest częścią parentContext, która jest ContextLoaderListener. Zatem kontekst nadrzędny nie może mieć zależności kontekstu potomnego. Dlatego najlepszą praktyką jest zapisywanie pliku spring-context.xml w contextparam zamiast zapisywać go w initparam.
źródło
Wierzę, że jego prawdziwe zastosowanie pojawia się, gdy chcesz mieć więcej niż jeden plik konfiguracyjny lub masz plik xyz.xml zamiast applicationcontext.xml, np.
<context-param><param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/training-service.xml, /WEB-INF/training-data.xml</param-value> </context-param>
Innym podejściem do ContextLoaderListener jest użycie ContextLoaderServlet, jak poniżej
<servlet> <servlet-name>context</servlet-name> <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet>
źródło