¿Por qué DispatcherServlet crea otro contexto de aplicación?

He configurado el contexto de la aplicación raíz usando ContextLoaderListener y el contexto init-parámetro contextConfigLocation .

El contexto raíz es luego accedido por JSF (* .jsf) variable-resolver. Funciona bien.

Ahora el problema es que las solicitudes (* .do) que pasan por DispatcherServlet obtendrán otro contexto de aplicación, y los beans singleton se instanciarán dos veces.

No necesito otro contexto de aplicación para DispatcherServlet , ¿cómo puedo especificar que vuelva a utilizar el contexto de la aplicación raíz existente, que carga ContextLoaderListener ?

NOTA

Después de leer las páginas de referencia en las respuestas, sé que hay una separación de contexto entre el contexto raíz y el contexto del despachador, pero ninguna de las referencias me dice a dónde ir. Así que aquí está mi solución, tal vez útil para otras personas que enfrentan la misma pregunta:

  1. En el XML de configuración de contexto para el servlet despachador: dispatcher-servlet.xml , he duplicado definido que ya está definido en el contexto raíz. Entonces quítalo. El dispatcher-servlet.xml solo tiene que definir los beans utilizados solo para Spring MVC.

  2. Todos los controladores ya han sido escaneados e instalados en el contexto raíz, sin embargo, Spring MVC de forma predeterminada no registra los controladores en el contexto raíz para las asignaciones de solicitudes. Tu también puedes:

    2.1. En el contexto raíz, excluya @Controller de , y escanee @Controller solo en dispatcher-servlet.xml.

    2.2. O bien, establezca la propiedad DefaultAnnotationHandlerMapping.detectHandlersInAncestorContexts en true:

     (dispatcher-servlet.xml:)    

Para responder a su primera pregunta, DispatcherServlet crea un contexto porque así es como se permite configurarlo, y si tiene varios DispatcherServlets en una aplicación, cada uno de ellos debe configurarse por separado. Por lo tanto, cada uno tiene su propio contexto, y cada uno de esos contextos está separado del contexto “raíz”, donde todos sus beans “en funcionamiento” reales deberían vivir para que puedan compartirse entre los otros contextos. Ha habido una serie de preguntas durante las últimas semanas que fueron generadas por la confusión sobre este mismo tema. Puede obtener una mejor comprensión de cómo funcionan las cosas al verificar las respuestas:

Ayuda / explicación de la jerarquía de configuración del archivo Spring XML

Declaración de Spring Bean en el contexto de los padres frente al contexto de los niños

Spring-MVC: ¿Qué son un “contexto” y un “espacio de nombres”?

Si tiene un DispatcherServlet ejecutándose, no es necesario usar ContextLoaderListener . Simplemente use ContextLoader.getCurrentWebApplicationContext() para acceder al WebApplicationContext .

Simplemente mantenga las definiciones de beans separadas como se describe en esta respuesta anterior .