ContextLoaderListener o no?

Resuelto Ralph asked hace 12 años • 3 respuestas

Una aplicación web Spring estándar (creada por Roo o plantilla "Spring MVC Project") crea un web.xml con ContextLoaderListenery DispatcherServlet. ¿Por qué no solo usan DispatcherServlety cargan la configuración completa?

Entiendo que ContextLoaderListener debe usarse para cargar cosas que no son relevantes para la web y DispatcherServlet se usa para cargar cosas relevantes para la web (Controladores,...). Y esto resulta en dos contextos: un contexto padre y un contexto hijo.

Fondo:

Lo estuve haciendo de esta manera estándar durante varios años.

<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>

Esto a menudo causaba problemas con los dos contextos y las dependencias entre ellos. En el pasado siempre pude encontrar una solución y tengo la fuerte sensación de que esto hace que la estructura/arquitectura del software sea siempre mejor. Pero ahora me enfrento a un problema con los acontecimientos de ambos contextos .

- Sin embargo, esto me hace reconsiderar estos dos patrones de contexto y me pregunto: ¿por qué debería meterme en este problema? ¿Por qué no cargar todos los archivos de configuración de Spring con uno DispatcherServlety eliminarlo ContextLoaderListenerpor completo? (Aún tendré diferentes archivos de configuración, pero solo un contexto).

¿Hay alguna razón para no eliminar el ContextLoaderListener?

Ralph avatar Jan 26 '12 16:01 Ralph
Aceptado

En su caso, no, no hay razón para conservar ContextLoaderListenery applicationContext.xml. Si su aplicación funciona bien solo con el contexto del servlet, siga con eso, es más simple.

Sí, el patrón generalmente recomendado es mantener el material que no es web en el contexto del nivel de la aplicación web, pero no es más que una convención débil.

Las únicas razones convincentes para utilizar el contexto a nivel de aplicación web son:

  • Si tiene varios DispatcherServletque necesitan compartir servicios
  • Si tiene servlets heredados/que no son de Spring y necesitan acceso a servicios conectados a Spring
  • Si tiene filtros de servlet que se conectan al contexto de nivel de aplicación web (por ejemplo, Spring Security DelegatingFilterProxy, OpenEntityManagerInViewFilteretc.)

Ninguno de estos se aplica a usted, por lo que la complejidad adicional no se justifica.

Solo tenga cuidado al agregar tareas en segundo plano al contexto del servlet, como tareas programadas, conexiones JMS, etc. Si olvida agregarlas <load-on-startup>a su archivo web.xml, estas tareas no se iniciarán hasta el primer acceso al servlet.

skaffman avatar Jan 26 '2012 09:01 skaffman

También puedes configurar el contexto de la aplicación al revés. Por ejemplo, para que OpenEntityManagerInViewFilter funcione. Configure ContextLoaderListener y luego configure su DispatcherServlet con:

<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></param-value>
    </init-param>
</servlet>

Solo asegúrese de que el valor del parámetro contextConfigLocation esté vacío.

Gunnar Hillert avatar Nov 27 '2013 21:11 Gunnar Hillert

Quiero compartir lo que hice en mi aplicación Spring-MVC:

  1. En el we-mvc-config.xmlagregué solo las clases anotadas con @Controller:

    <context:component-scan base-package="com.shunra.vcat">
        <context:include-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
    </context:component-scan>
    
  2. En los applicationContext.xmlarchivos agregué todo el resto:

    <context:component-scan base-package="com.shunra.vcat">
        <context:exclude-filter expression="org.springframework.stereotype.Controller" type="annotation"/>
    </context:component-scan>
    
Modi avatar Dec 25 '2012 16:12 Modi