Ich lerne Spring Framework , das in meinem Projekt verwendet wird. Ich habe den Eintrag ContextLoaderListener in meiner Datei web.xml gefunden . Aber konnten Sie nicht herausfinden, wie genau es einem Entwickler hilft?
In der offiziellen Dokumentation von ContextLoaderListener heißt es, dass WebApplicationContext gestartet werden soll . In Bezug auf WebApplicationContext sagen JavaDocs:
Schnittstelle zur Konfiguration einer Webanwendung.
Aber ich kann nicht verstehen, was ich mit ContextLoaderListener erreiche, der den WebApplicationContext intern initialisiert .
Gemäß meinem Verständnis , Context liest die Spring - Konfigurationsdatei (mit dem Wert gegeben gegen contextConfigLocation in web.xml ), analysiert es und lädt der Singleton - Bean in dieser Konfigurationsdatei definiert. Wenn wir eine Prototyp-Bean laden möchten, verwenden wir zum Laden denselben Webanwendungskontext. Daher initialisieren wir die Webanwendung mit ContextLoaderListener, sodass wir die Konfigurationsdatei im Voraus lesen / analysieren / validieren und wann immer wir Abhängigkeiten einfügen möchten , können wir dies sofort und ohne Verzögerung tun. Ist dieses Verständnis richtig?
quelle
Antworten:
Dein Verständnis ist korrekt. Hier
ApplicationContext
leben Ihre Frühlingsbohnen. Der Zweck desContextLoaderListener
ist zweifach:den Lebenszyklus des und
ApplicationContext
an den Lebenszyklus desServletContext
und zu bindenUm die Erstellung des zu automatisieren
ApplicationContext
, müssen Sie keinen expliziten Code schreiben, um es zu erstellen - es ist eine praktische Funktion.Eine weitere praktische Sache
ContextLoaderListener
ist, dass es eine erstelltWebApplicationContext
undWebApplicationContext
Zugriff auf dieServletContext
ViaServletContextAware
Beans und diegetServletContext
Methode bietet .quelle
WebApplicationContext
. Andernfalls müsste es manuell erstellt werden.ContextLoaderListener
implementieren eine Methode destroy alle Bohnen , wenn die Web - Container Fahren zu zerstören?contextDestroyed
es aufgerufen wird. Siehe die API-Dokumente.web.xml
. In meiner XML-Datei gibt es zwei ListenerContextLoaderListener
undDispatcherServlet
. Ich denke, es gibt keine Notwendigkeit für beides. Ist es sicher zu entfernen,ContextLoaderListener
warum ich frage, weil die Anwendung seit 7-8 Monaten live ist? web.xml ist hier für Ihre Referenz.ContextLoaderListener
ist optional . Um hier einen Punkt zu verdeutlichen: Sie können eine Spring-Anwendung starten, ohne sie jemals zu konfigurierenContextLoaderListener
, nur ein grundlegendes Minimumweb.xml
mitDispatcherServlet
.So würde es aussehen:
web.xml
Erstellen Sie eine Datei mit dem Namen
dispatcher-servlet.xml
und speichern Sie sie unterWEB-INF
. Da wirindex.jsp
in der Begrüßungsliste erwähnt haben , fügen Sie diese Datei unter hinzuWEB-INF
.dispatcher-servlet.xml
In der
dispatcher-servlet.xml
Definition Ihrer Bohnen:quelle
Für eine einfache Spring-Anwendung müssen Sie nicht
ContextLoaderListener
in Ihrem definierenweb.xml
; Sie können einfach alle Ihre Spring-Konfigurationsdateien ablegen in<servlet>
:Für eine komplexere Spring-Anwendung, in der Sie mehrere
DispatcherServlet
definiert haben, können Sie die allgemeinen Spring-Konfigurationsdateien verwenden, die von allenDispatcherServlet
inContextLoaderListener
:Denken Sie daran,
ContextLoaderListener
führt die eigentliche Initialisierungsarbeit für den Stammanwendungskontext aus .Ich fand, dass dieser Artikel sehr hilfreich ist: Spring MVC - Anwendungskontext vs Webanwendungskontext
quelle
Der Blog " Zweck von ContextLoaderListener - Spring MVC " gibt eine sehr gute Erklärung.
Demnach sind Anwendungskontexte hierarchisch und daher wird der Kontext von DispatcherSerlvet zum untergeordneten Kontext von ContextLoaderListener. Aufgrund dessen kann die in der Controller-Schicht verwendete Technologie (Struts oder Spring MVC) unabhängig vom im Stammkontext erstellten ContextLoaderListener erstellt werden.
quelle
Wenn Sie Ihre Servlet-Datei an Ihrem benutzerdefinierten Speicherort oder mit einem benutzerdefinierten Namen anstelle der Standard-Namenskonvention
[servletname]-servlet.xml
und des Pfads unter ablegen möchten,Web-INF/
können Sie sie verwendenContextLoaderListener
.quelle
ContextLoaderListner ist ein Servlet-Listener, der alle verschiedenen Konfigurationsdateien (Service-Layer-Konfiguration, Persistenz-Layer-Konfiguration usw.) in einen einzelnen Spring-Anwendungskontext lädt.
Dies hilft, Federkonfigurationen auf mehrere XML-Dateien aufzuteilen.
Sobald die Kontextdateien geladen sind, erstellt Spring ein WebApplicationContext-Objekt basierend auf der Bean-Definition und speichert es im ServletContext Ihrer Webanwendung.
quelle
Dieser Bootstrap-Listener dient zum Starten und Herunterfahren von Spring's Root- WebApplicationContext. Da eine Webanwendung über mehrere Dispatcher-Servlets verfügen kann und jedes über einen eigenen Anwendungskontext verfügt, der Controller, Ansichtsauflöser, Handlerzuordnungen usw. enthält. Möglicherweise möchten Sie jedoch Service-Beans und DAO-Beans im Kontext der Stammanwendung haben und in allen untergeordneten Anwendungskontexten verwenden ( Anwendungskontext, der von Dispatcher-Servlets erstellt wurde).
Die zweite Verwendung dieses Listeners ist, wenn Sie die Federsicherheit verwenden möchten.
quelle
Wurzel- und Kinderkontexte Bevor Sie weiterlesen, verstehen Sie bitte, dass -
Der Frühling kann mehrere Kontexte gleichzeitig haben. Einer von ihnen ist der Stammkontext, und alle anderen Kontexte sind untergeordnete Kontexte.
Alle untergeordneten Kontexte können auf die im Stammkontext definierten Beans zugreifen. aber das Gegenteil ist nicht wahr. Der Stammkontext kann nicht auf untergeordnete Kontext-Beans zugreifen.
Anwendungskontext:
applicationContext.xml ist die Stammkontextkonfiguration für jede Webanwendung. Spring lädt die Datei applicationContext.xml und erstellt den ApplicationContext für die gesamte Anwendung. Pro Webanwendung gibt es nur einen Anwendungskontext. Wenn Sie den Namen der Kontextkonfigurationsdatei in web.xml nicht explizit mit dem Parameter contextConfigLocation deklarieren, sucht Spring im Ordner WEB-INF nach applicationContext.xml und löst FileNotFoundException aus, wenn diese Datei nicht gefunden werden konnte.
ContextLoaderListener Führt die eigentliche Initialisierungsarbeit für den Stammanwendungskontext aus. Liest einen Kontextparameter "contextConfigLocation" und übergibt seinen Wert an die Kontextinstanz. Dabei wird er in möglicherweise mehrere Dateipfade analysiert, die durch eine beliebige Anzahl von Kommas und Leerzeichen getrennt werden können, z. B. "WEB-INF / applicationContext1.xml, WEB-INF /" applicationContext2.xml ”. ContextLoaderListener ist optional. Um hier einen Punkt zu verdeutlichen: Sie können eine Spring-Anwendung starten, ohne jemals ContextLoaderListener zu konfigurieren, nur eine grundlegende minimale web.xml mit DispatcherServlet.
DispatcherServlet DispatcherServlet ist im Wesentlichen ein Servlet (es erweitert HttpServlet), dessen Hauptzweck darin besteht, eingehende Webanforderungen zu verarbeiten, die dem konfigurierten URL-Muster entsprechen. Es nimmt eine eingehende URI und findet die richtige Kombination aus Controller und Ansicht. Es ist also der Frontcontroller.
Wenn Sie ein DispatcherServlet in der Frühjahrskonfiguration definieren, stellen Sie eine XML-Datei mit Einträgen von Controller-Klassen, Ansichtszuordnungen usw. mithilfe des Attributs contextConfigLocation bereit.
WebApplicationContext Neben ApplicationContext können in einer Webanwendung mehrere WebApplicationContext vorhanden sein. Mit einfachen Worten, jedes DispatcherServlet, das einem einzelnen WebApplicationContext zugeordnet ist. Die Datei xxx-servlet.xml ist spezifisch für das DispatcherServlet. In einer Webanwendung kann mehr als ein DispatcherServlet für die Verarbeitung der Anforderungen konfiguriert sein. In solchen Szenarien würde für jedes DispatcherServlet eine separate xxx-servlet.xml konfiguriert sein. ApplicationContext.xml ist jedoch für alle Servlet-Konfigurationsdateien gleich. Spring lädt standardmäßig die Datei "xxx-servlet.xml" aus Ihrem WEB-INF-Ordner für Webanwendungen, wobei xxx der Servlet-Name in web.xml ist. Wenn Sie den Namen dieses Dateinamens oder den Speicherort ändern möchten, fügen Sie initi-param mit contextConfigLocation als Parameternamen hinzu.
Vergleich und Beziehung zwischen ihnen:
ContextLoaderListener vs DispatcherServlet
ContextLoaderListener erstellt den Stammanwendungskontext. DispatcherServlet-Einträge erstellen einen untergeordneten Anwendungskontext pro Servlet-Eintrag. Untergeordnete Kontexte können auf Beans zugreifen, die im Stammkontext definiert sind. Beans im Stammkontext können (direkt) nicht auf Beans in untergeordneten Kontexten zugreifen. Alle Kontexte werden zu ServletContext hinzugefügt. Sie können mit der WebApplicationContextUtils-Klasse auf den Stammkontext zugreifen.
Nach dem Lesen der Spring-Dokumentation gilt Folgendes:
a) Anwendungskontexte sind hierarchisch, ebenso wie WebApplicationContexts. Siehe Dokumentation hier.
b) ContextLoaderListener erstellt einen Root-Webanwendungskontext für die Webanwendung und fügt ihn in den ServletContext ein. Dieser Kontext kann zum Laden und Entladen der Spring-Managed-Beans verwendet werden, unabhängig davon, welche Technologie in der Controller-Schicht (Struts oder Spring MVC) verwendet wird.
c) DispatcherServlet erstellt einen eigenen WebApplicationContext und die Handler / Controller / View-Resolver werden von diesem Kontext verwaltet.
d) Wenn ContextLoaderListener zusammen mit DispatcherServlet verwendet wird, wird zuerst ein Root-Webanwendungskontext erstellt, und ein untergeordneter Kontext wird ebenfalls von DispatcherSerlvet erstellt und an den Root-Anwendungskontext angehängt. Siehe Dokumentation hier.
Wenn wir mit Spring MVC arbeiten und Spring auch in der Serviceschicht verwenden, stellen wir zwei Anwendungskontexte bereit. Der erste wird mit ContextLoaderListener und der andere mit DispatcherServlet konfiguriert
Im Allgemeinen definieren Sie alle MVC-bezogenen Beans (Controller und Ansichten usw.) im DispatcherServlet-Kontext und alle übergreifenden Beans wie Sicherheit, Transaktion, Dienste usw. im Stammkontext von ContextLoaderListener.
Weitere Informationen finden Sie hier: https://siddharthnawani.blogspot.com/2019/10/contextloaderlistener-vs.html
quelle
Grundsätzlich können Sie Ihren Stammanwendungskontext und den Webanwendungskontext mit ContextLoaderListner isolieren.
Die mit context param zugeordnete Konfigurationsdatei verhält sich wie die Kontextkonfiguration der Stammanwendung. Die mit dem Dispatcher-Servlet zugeordnete Konfigurationsdatei verhält sich wie der Kontext einer Webanwendung.
In jeder Webanwendung können mehrere Dispatcher-Servlets vorhanden sein, also mehrere Webanwendungskontexte.
In jeder Webanwendung haben wir jedoch möglicherweise nur einen Stammanwendungskontext, der für alle Webanwendungskontexte freigegeben ist.
Wir sollten unsere gemeinsamen Dienste, Entitäten, Aspekte usw. im Kontext der Stammanwendung definieren. Controller, Interceptors usw. befinden sich im relevanten Webanwendungskontext.
Ein Beispiel für web.xml ist
Hier kann die Konfigurationsklasse example.config.AppConfig verwendet werden, um Dienste, Entitäten, Aspekte usw. im Stammanwendungskontext zu konfigurieren, die für alle anderen Webanwendungskontexte freigegeben werden (hier haben wir beispielsweise zwei Konfigurationsklassen für den Webanwendungskontext RestConfig und WebConfig).
PS: Hier ist ContextLoaderListener völlig optional. Wenn wir ContextLoaderListener hier in web.xml nicht erwähnen, funktioniert AppConfig nicht. In diesem Fall müssen wir alle unsere Dienste und Entitäten in WebConfig und Rest Config konfigurieren.
quelle
Sie erhalten einen Haken, um Code einzufügen, der zur Bereitstellungszeit der Webanwendung ausgeführt werden soll
quelle
Listener-Klasse - Hört ein Ereignis ab (z. B. Starten / Herunterfahren des Servers)
ContextLoaderListener -
Konfigurationsdateien können wie folgt in web.xml bereitgestellt werden
quelle
Im Kontext des Spring Frameworks dient ContextLoaderListener dazu, die anderen Beans in Ihrer Anwendung zu laden, z. B. die Komponenten der mittleren und Datenebene , die das Back-End der Anwendung steuern .
quelle
Dein Verständnis ist korrekt. Ich frage mich, warum Sie in ContextLoaderListener keine Vorteile sehen. Beispielsweise müssen Sie eine Sitzungsfactory erstellen (um die Datenbank zu verwalten). Dieser Vorgang kann einige Zeit dauern, daher ist es besser, ihn beim Start auszuführen. Natürlich können Sie dies mit Init-Servlets oder etwas anderem tun, aber der Vorteil von Spring besteht darin, dass Sie die Konfiguration vornehmen, ohne Code zu schreiben.
quelle
Wenn wir web.xml ohne ContextLoaderListener schreiben, können wir die Athuntication nicht mit customAuthenticationProvider in Spring Security geben. Da DispatcherServelet der untergeordnete Kontext von ContextLoaderListener ist, ist customAuthenticationProvider der Teil von parentContext, der ContextLoaderListener ist. Der übergeordnete Kontext kann also nicht die Abhängigkeiten des untergeordneten Kontexts haben. Daher ist es empfehlenswert, spring-context.xml in contextparam zu schreiben, anstatt es in initparam zu schreiben.
quelle
Ich glaube, seine wirkliche Verwendung kommt, wenn Sie mehr als eine Konfigurationsdatei haben möchten oder wenn Sie die Datei xyz.xml anstelle von applicationcontext.xml haben, z
<context-param><param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/training-service.xml, /WEB-INF/training-data.xml</param-value> </context-param>
Ein anderer Ansatz für ContextLoaderListener ist die Verwendung von ContextLoaderServlet wie unten
<servlet> <servlet-name>context</servlet-name> <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet>
quelle