Eine Standard-Spring-Webanwendung (erstellt von Roo oder der Vorlage "Spring MVC Project") erstellt eine web.xml mit ContextLoaderListener
und DispatcherServlet
. Warum verwenden sie nicht nur das DispatcherServlet
und machen es, um die komplette Konfiguration zu laden?
Ich verstehe, dass der ContextLoaderListener zum Laden der nicht webrelevanten Inhalte verwendet werden sollte und das DispatcherServlet zum Laden der webrelevanten Inhalte (Controller, ...). Dies führt zu zwei Kontexten: einem übergeordneten und einem untergeordneten Kontext.
Hintergrund:
Ich habe es mehrere Jahre lang auf diese übliche Weise gemacht.
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:META-INF/spring/applicationContext*.xml</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Handles Spring requests -->
<servlet>
<servlet-name>roo</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>WEB-INF/spring/webmvc-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
Dies verursachte häufig Probleme mit den beiden Kontexten und den Abhängigkeiten zwischen ihnen. In der Vergangenheit konnte ich immer eine Lösung finden, und ich habe das starke Gefühl, dass dies die Softwarestruktur / -architektur immer besser macht. Aber jetzt stehe ich vor einem Problem mit den Ereignissen beider Kontexte .
- Dies lässt mich jedoch diese beiden Kontextmuster überdenken, und ich frage mich: Warum sollte ich mich in diese Schwierigkeiten bringen, warum nicht alle Federkonfigurationsdateien mit einer laden DispatcherServlet
und die ContextLoaderListener
vollständig entfernen . (Ich werde immer noch verschiedene Konfigurationsdateien haben, aber nur einen Kontext.)
Gibt es einen Grund, das nicht zu entfernen ContextLoaderListener
?
Antworten:
In Ihrem Fall gibt es keinen Grund, das
ContextLoaderListener
und beizubehaltenapplicationContext.xml
. Wenn Ihre App nur mit dem Kontext des Servlets funktioniert, bleibt dies einfacher.Ja, das allgemein empfohlene Muster besteht darin, Nicht-Web-Inhalte im Kontext auf Webanwendungsebene zu belassen, aber es ist nichts weiter als eine schwache Konvention.
Die einzigen zwingenden Gründe für die Verwendung des Kontexts auf Webanwendungsebene sind:
DispatcherServlet
, die Dienste gemeinsam nutzen müssenDelegatingFilterProxy
,OpenEntityManagerInViewFilter
usw.)Keines davon trifft auf Sie zu, sodass die zusätzliche Komplexität nicht gerechtfertigt ist.
Seien Sie vorsichtig, wenn Sie dem Kontext des Servlets Hintergrundaufgaben hinzufügen, z. B. geplante Aufgaben, JMS-Verbindungen usw. Wenn Sie vergessen
<load-on-startup>
, Ihreweb.xml
Aufgaben hinzuzufügen , werden diese Aufgaben erst beim ersten Zugriff auf das Servlet gestartet.quelle
DispatcherServlet
ohne Konfiguration - wenn du das getan hast, dann würden Sie keine Web - Oberfläche haben. Alle MVC-Sachen müssen da rein.Sie können den Anwendungskontext auch umgekehrt konfigurieren. Zum Beispiel, damit der OpenEntityManagerInViewFilter funktioniert. Richten Sie den ContextLoaderListener ein und konfigurieren Sie Ihr DispatcherServlet mit:
Stellen Sie einfach sicher, dass der Parameterwert contextConfigLocation leer ist.
quelle
Ich möchte mitteilen, was ich in meiner Spring-MVC-Anwendung getan habe:
Auf dem habe
we-mvc-config.xml
ich nur die mit @Controller annotierten Klassen hinzugefügt:Zu den
applicationContext.xml
Dateien habe ich den Rest hinzugefügt:quelle