2010-09-13 11 views
9

Ich habe mir eine Reihe von Beispielprojekten angeschaut und ich kann nicht scheinen, eine gemeinsame Best Practice herauszukitzeln. Ich habe gesehen, Spring Bean Konfigurationsdateien gehen manchmal in das Verzeichnis src/main/webapp/WEB-INF. Ich habe dies in web.xml wie dies mit einer Servlet-Definition in Verbindung gesehen:Wohin gehen Spring-Bean-Konfigurationsdateien in einem Maven-WAR-Modul?

<servlet> 
    <servlet-name>my-stuff</servlet-name> 
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
    <init-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value>/WEB-INF/my-stuff-servlet.xml</param-value> 
    </init-param> 
    <load-on-startup>1</load-on-startup> 
</servlet> 

Aber ich habe auch Bean-Konfigurationsdateien enthalten innerhalb web.xml obersten Ebene gesehen - das heißt außerhalb eines Servlets. Was bedeutet das? Ist dies für Cross-Servlet-Bohnen? Manchmal ist es im Verzeichnis src/main/webapp/WEB-INF und manchmal in src/main/resources. Ich habe auch andere Bean-Konfigurationsdateien gesehen, die in WAR-Modulen mit fast allem in src/main/resources definiert wurden.

Ich habe die Spring-Dokumentation gelesen und gelesen, aber die einzige Konvention, die ich gefunden habe, ist, dass eine Servlet-Kontextkonfigurationsdatei standardmäßig im Verzeichnis src/main/webapp/WEB-INF mit dem Namen {servlet-name}-servlet.xml sein sollte.

Also, was ist die beste Praxis und warum?

Antwort

12

Anwendungskontexte in Spring können Hierarchien bilden, in denen der untergeordnete Kontext Zugriff auf im übergeordneten Kontext definierte Beans hat.

Eine typische Spring MVC Web-Anwendung enthält eine Hierarchie mit zwei Ebenen:

  • Stammkontext Web-Anwendung geladen durch ContextLoaderListener. Der Speicherort dieses Kontexts ist standardmäßig applicationContext.xml und kann unter Verwendung von <context-param> mit dem Namen contextConfigLocation konfiguriert werden, d. H. Auf der obersten Ebene von web.xml. Dieser Kontext enthält normalerweise eine Kernanwendungslogik.

  • Servletspezifischer Kontext geladen von DispatcherServlet. Die Konfigurationsposition ist standardmäßig <servletname>-servlet.xml und kann unter Verwendung von <init-param> mit dem Namen contextConfigLocation, d. H. Auf Servlet-Ebene, konfiguriert werden. Dieser Kontext enthält normalerweise ein Spring MVC-bezogenes Zeug (Controller usw.), da DispatcherServlet ein Teil von Spring MVC ist.

Der letztere Kontext ist ein Kind der ehemaligen.

Wenn Webanwendung Spring MVC nicht als Präsentationsframework verwendet, hat es DispatcherServlet und seinen Kontext nicht. Einige sehr einfache Spring MVC-Beispiele haben ContextLoaderListener und den Stammkontext nicht (Sie benötigen jedoch einen Stammkontext für Cross-Servlet-Funktionen wie Spring Security).

Die Konfigurationsdateien der Webanwendung befinden sich standardmäßig im Stammordner der Webanwendung. Sie können jedoch in den Klassenpfad platziert werden (d. H. In src/main/webapp), in diesem Fall wird auf sie über das Präfix classpath: zugegriffen. Dies kann nützlich sein, wenn Sie einige dieser Dateien in Integrationstests ohne Servlet-Container verwenden möchten. Auch das Präfix classpath: kann nützlich sein, wenn Sie eine Konfigurationsdatei von einem separaten Artefakt laden möchten, d. H. Von einer JAR-Datei in /WEB-INF/lib.

+0

Sehr hilfreich - danke. Ich wünschte, dies wurde in den Frühlingsdokumenten so gut erklärt! – HDave

+0

@HDave Das ist nicht Spring-spezifisch, es ist normales Java-Classloader-Verhalten (das einzige Ding, das springspezifisch ist, ist das 'classpath:' -Präfix) –

2

Ich denke, es ist oft guter Stil, den Code zu behalten, seine Spring-Konfiguration in einem separaten JAR, das in der WAR enthalten ist, so dass der WAR im Grunde leer ist, aber für web.xml und dergleichen. Dadurch ersparen Sie sich diese Frage. :-) Sie können diese Federkonfigurationen mit classpath: prefix referenzieren.

Ein Vorteil dieses Layouts besteht darin, dass Sie problemlos Unittests schreiben können, die die vollständige Spring-Konfiguration des WAR innerhalb des JAR instanziieren. Ich würde nicht unbedingt empfehlen, dies für tatsächliche Tests zu verwenden (obwohl Sie Integrationstests auf diese Weise durchführen können), aber Sie erhalten eine schnelle Rückmeldung, wenn Sie versehentlich die Gesamtstruktur der Konfigurationsdateien durchbrechen, ohne die Anwendung erneut bereitstellen zu müssen.

Wenn Sie wirklich Frühlingskonfigurationsdateien in den WAR legen müssen (vielleicht weil es auch Beans referenziert, die im WAR selbst implementiert sind), würde ich sie auch in den normalen Ressourcenpfad/WEB-INF/classes einfügen oben diskutierte Gründe.

+0

Ich stimme dem zu und habe bereits alle Spring-Konfigurationsdateien auf Modulebene in diesen Modul-JARs - genau aus dem Grund, den Sie erwähnen ... Integrationstest. Es gibt jedoch immer noch Spring-Konfigurationsdateien von WAR, die ich erstellt habe, um Instanzen zu erstellen, die vom Servlet-Container usw. konsumiert werden. Ich landete sie einfach im Verzeichnis {{webapp}}. – HDave

+0

@HDave Ich würde solche Dateien in/WEB-INF/-Klassen platzieren, so dass sie auch im Classpath sind. So können Sie sie zumindest in der Einheit testen. –

Verwandte Themen