2009-03-01 15 views
55

¿Cuál es la forma correcta de dividir la configuración de Spring en varios archivos xml?División de aplicaciónContext en varios archivos

Por el momento no tengo

  • /WEB-INF/foo-servlet.xml
  • /WEB-INF/foo-service.xml
  • /WEB-INF/foo-persistence.xml

Mi web.xml tiene la siguiente:

<servlet> 
    <description>Spring MVC Dispatcher Servlet</description> 
    <servlet-name>intrafest</servlet-name> 
    <servlet-class> 
     org.springframework.web.servlet.DispatcherServlet 
    </servlet-class> 
    <init-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value> 
      /WEB-INF/foo-*.xml 
     </param-value> 
    </init-param> 
    <load-on-startup>2</load-on-startup> 
</servlet> 

<context-param> 
    <param-name>contextConfigLocation</param-name> 
    <param-value> 
      /WEB-INF/foo-*.xml 
    </param-value> 
</context-param> 


<listener> 
    <listener-class> 
     org.springframework.web.context.ContextLoaderListener 
    </listener-class> 
</listener> 

Las preguntas reales:

  • es el enfoque correcto / mejor?
  • ¿Realmente necesito especificar las ubicaciones de configuración en las secciones DispatcherServletYcontext-param?

¿Qué necesito para tener en cuenta para poder referenciar beans definidos en foo-servlet.xml de foo-service.xml? ¿Tiene esto algo que ver con la especificación de contextConfigLocation en web.xml?

Actualización 1:

estoy usando primavera marco 3.0. Tengo entendido que no necesito importar recursos de esta manera:

<import resource="foo-services.xml"/> 

¿Es esto una suposición correcta?

Respuesta

47

Creo que la siguiente configuración es la más fácil.

utilizar el mecanismo de carga del archivo de configuración por defecto de DispatcherServlet:

El marco de referencia, en la inicialización de un DispatcherServlet, busque un archivo llamado [servlet-name] -servlet.xml en la WEB -INF directorio de su aplicación web y crear los beans definidos allí (anulando las definiciones de los beans definidos con del mismo nombre en el ámbito global).

En su caso, cree un archivo intrafest-servlet.xml en el WEB-INF dir y no es necesario especificar la información específica nada en web.xml.

En el archivo intrafest-servlet.xml puede usar import para componer su configuración XML.

<beans> 
    <bean id="bean1" class="..."/> 
    <bean id="bean2" class="..."/> 

    <import resource="foo-services.xml"/> 
    <import resource="foo-persistence.xml"/> 
</beans> 

Tenga en cuenta que el equipo de Primavera en realidad prefiere cargar varios archivos de configuración cuando se crea el (la web) Application Context.Si todavía desea hacerlo de esta manera, creo que no necesita especificar parámetros de contexto (context-param) y parámetros de inicialización de servlet (init-param). Uno de los dos servirá. También puede usar comas para especificar múltiples ubicaciones de configuración.

+0

+1 - mi configuración se parece a esto. Aunque no creo que haya realmente ventajas/desventajas prácticas para esta configuración frente a la especificación de múltiples archivos de configuración en web.xml, parece una semántica –

+1

. Definitivamente creo que la configuración predeterminada es ventajosa: convención sobre la configuración. En lugar de especificar múltiples archivos de configuración con * configuración adicional *, solo tiene un archivo de configuración de "nivel superior" * predeterminado que importará esos mismos archivos que de otra manera tendría que especificar de todos modos. – eljenso

+1

Cuando usa importación, tenga cuidado de no importar el mismo archivo varias veces, (importar dentro de importación, etc.), ya que causará la creación de varios beans y dará lugar a errores difíciles de encontrar. –

6

@eljenso: intrafest-servlet.xml webapplication context xml se usará si la aplicación utiliza SPRING WEB MVC.

De lo contrario, la configuración @kosoant está bien.

ejemplo simple, si usted no utiliza MUELLE WEB MVC, pero quieren utitlize MUELLE COI:

En web.xml:

<context-param> 
     <param-name>contextConfigLocation</param-name> 
     <param-value>classpath:application-context.xml</param-value> 
</context-param> 

Entonces, su aplicación de context.xml contendrá: <import resource="foo-services.xml"/> estas instrucciones de importación para cargar varios archivos de contexto de la aplicación y ponerlos en la aplicación principal-context.xml.

Gracias y espero que esto ayude.

25

Mike Nereson tiene esto que decir en su blog en:

http://blog.codehangover.com/load-multiple-contexts-into-spring/

Hay un par de maneras de hacer esto.

1. Web.xml contextConfigLocation

Su primera opción es cargar a todos en su aplicación Web contexto a través del elemento ContextConfigLocation. Ya va al para tener su ApplicationContext principal aquí, suponiendo que está escribiendo una aplicación web. Todo lo que necesita hacer es poner un espacio en blanco entre la declaración del siguiente contexto.

<context-param> 
     <param-name> contextConfigLocation </param-name> 
     <param-value> 
      applicationContext1.xml 
      applicationContext2.xml 
     </param-value> 
    </context-param> 

    <listener> 
     <listener-class> 
      org.springframework.web.context.ContextLoaderListener 
     </listener-class> 
    </listener> 

Lo anterior utiliza el retorno de carro. Alternativamente, podría simplemente poner en un espacio .

<context-param> 
     <param-name> contextConfigLocation </param-name> 
     <param-value> applicationContext1.xml applicationContext2.xml </param-value> 
    </context-param> 

    <listener> 
     <listener-class> org.springframework.web.context.ContextLoaderListener </listener-class> 
    </listener> 

2. recursos importación applicationContext.xml

Su otra opción es simplemente añada su applicationContext.xml primaria al web.xml y luego utilizar las declaraciones de importación en ese contexto primario.

En applicationContext.xml es posible que tenga ...

<!-- hibernate configuration and mappings --> 
    <import resource="applicationContext-hibernate.xml"/> 

    <!-- ldap --> 
    <import resource="applicationContext-ldap.xml"/> 

    <!-- aspects --> 
    <import resource="applicationContext-aspects.xml"/> 

Qué estrategia se debe utilizar?

1. siempre prefiero que cargar a través de Web.xml.

Porque, esto me permite mantener todos los contextos aislados de cada otro.Con las pruebas, podemos cargar solo los contextos que necesitamos para ejecutar esas pruebas. Esto hace que el desarrollo sea más modular también, ya que los componentes permanecen en loosely coupled, por lo que en el futuro puedo extraer un paquete o capa vertical y moverlo a su propio módulo.

2. Si está cargando contextos en un non-web application, me gustaría utilizar el recurso import.

+10

Copias del artículo http://blog.codehangover.com/load-multiple-contexts-into-spring/ sin cita. –

11

Hay dos tipos de contextos que nos ocupan:

: (. Contexto padres suelen incluir todas JDBC (ORM, Hibernate) de seguridad de configuración relacionados con la inicialización y otro resorte) contexto raíz

: contexto de servlet individual (contexto secundario. Servlet típico del despachador Contexto e inicialización de todos los beans relacionados con spring-mvc (controladores, asignación de URL, etc.)).

Aquí es un ejemplo de web.xml que incluye archivo de contexto de múltiples aplicaciones

<?xml version="1.0" encoding="UTF-8"?> 
 
<web-app xmlns="http://java.sun.com/xml/ns/javaee" 
 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 
     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
 
          http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> 
 

 
    <display-name>Spring Web Application example</display-name> 
 

 
    <!-- Configurations for the root application context (parent context) --> 
 
    <listener> 
 
     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
 
    </listener> 
 
    <context-param> 
 
     <param-name>contextConfigLocation</param-name> 
 
     <param-value> 
 
      /WEB-INF/spring/jdbc/spring-jdbc.xml <!-- JDBC related context --> 
 
      /WEB-INF/spring/security/spring-security-context.xml <!-- Spring Security related context --> 
 
     </param-value> 
 
    </context-param> 
 

 
    <!-- Configurations for the DispatcherServlet application context (child context) --> 
 
    <servlet> 
 
     <servlet-name>spring-mvc</servlet-name> 
 
     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
 
     <init-param> 
 
      <param-name>contextConfigLocation</param-name> 
 
      <param-value> 
 
       /WEB-INF/spring/mvc/spring-mvc-servlet.xml 
 
      </param-value> 
 
     </init-param> 
 
    </servlet> 
 
    <servlet-mapping> 
 
     <servlet-name>spring-mvc</servlet-name> 
 
     <url-pattern>/admin/*</url-pattern> 
 
    </servlet-mapping> 
 

 
</web-app>

+0

Gran respuesta. La distinción entre raíz y elemento secundario es clave. – MrKiller21

1

Soy el autor de modular-spring-contexts.

Esta es una pequeña biblioteca de utilidades para permitir una organización más modular de los contextos de resorte que la que se obtiene al usar Composing XML-based configuration metadata. modular-spring-contexts funciona definiendo módulos, que son básicamente contextos de aplicaciones independientes y que permiten a los módulos importar beans de otros módulos, que se exportan a su módulo de origen. entonces

Los puntos clave son

  • control sobre las dependencias entre módulos
  • de control sobre los que se exportan granos y donde se utilizan
  • posibilidad reducida de nombrar las colisiones de granos de

Un ejemplo simple se vería así:

Archivo moduleDefinitions.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:module="http://www.gitlab.com/SpaceTrucker/modular-spring-contexts" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
         http://www.gitlab.com/SpaceTrucker/modular-spring-contexts xsd/modular-spring-contexts.xsd 
         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> 

    <context:annotation-config /> 

    <module:module id="serverModule"> 
     <module:config location="/serverModule.xml" /> 
    </module:module> 

    <module:module id="clientModule"> 
     <module:config location="/clientModule.xml" /> 
     <module:requires module="serverModule" /> 
    </module:module> 

</beans> 

Archivo serverModule.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:module="http://www.gitlab.com/SpaceTrucker/modular-spring-contexts" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
         http://www.gitlab.com/SpaceTrucker/modular-spring-contexts xsd/modular-spring-contexts.xsd 
         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> 

    <context:annotation-config /> 

    <bean id="serverSingleton" class="java.math.BigDecimal" scope="singleton"> 
     <constructor-arg index="0" value="123.45" /> 
     <meta key="exported" value="true"/> 
    </bean> 

</beans> 

Archivo clientModule.xml

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:module="http://www.gitlab.com/SpaceTrucker/modular-spring-contexts" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
         http://www.gitlab.com/SpaceTrucker/modular-spring-contexts xsd/modular-spring-contexts.xsd 
         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> 

    <context:annotation-config /> 

    <module:import id="importedSingleton" sourceModule="serverModule" sourceBean="serverSingleton" /> 

</beans> 
+0

gracias @SpaceTrucker! parece que has creado exactamente lo que también necesitamos. no estoy seguro de por qué la rica comunidad de primavera no creó algo similar antes ... – ashirman