Estoy aprendiendo Spring Framework que se está utilizando en mi proyecto. Encontré la entrada ContextLoaderListener en mi archivo web.xml . ¿Pero no pudo entender exactamente cómo ayuda a un desarrollador?
En la documentación oficial de ContextLoaderListener dice que es para iniciar WebApplicationContext . Con respecto a WebApplicationContext, los JavaDoc dicen:
Interfaz para proporcionar configuración para una aplicación web.
¿Pero no puedo entender lo que estoy logrando con ContextLoaderListener que internamente inicializa el WebApplicationContext ?
Según tengo entendido , ContextLoaderListener lee el archivo de configuración de Spring (con el valor dado contra contextConfigLocation en web.xml ), lo analiza y carga el bean singleton definido en ese archivo de configuración. De manera similar, cuando queremos cargar el prototipo de bean , usaremos el mismo contexto de aplicación web para cargarlo. Entonces, inicializamos la aplicación web con ContextLoaderListener para que podamos leer / analizar / validar el archivo de configuración de antemano y siempre que queramos inyectar dependencia podemos hacerlo inmediatamente sin demora. ¿Es correcto este entendimiento?
fuente
Respuestas:
Su comprensión es correcta. Aquí
ApplicationContext
es donde viven tus frijoles de primavera. El propósito de laContextLoaderListener
es doble:para vincular el ciclo de vida de la
ApplicationContext
con el ciclo de vida de laServletContext
ypara automatizar la creación de
ApplicationContext
, para que no tenga que escribir código explícito para crearlo, es una función conveniente.Otra cosa conveniente acerca de esto
ContextLoaderListener
es que creaWebApplicationContext
yWebApplicationContext
proporciona acceso a los beansServletContext
víaServletContextAware
y algetServletContext
método.fuente
WebApplicationContext
. De lo contrario, debería crearse manualmente.ContextLoaderListener
implementa un método de destrucción para destruir todos los beans cuando el contenedor web se cierra?contextDestroyed
se llama. Ver los documentos de la API.web.xml
. En mi archivo xml hay dos oyentesContextLoaderListener
yDispatcherServlet
. Así que supongo que no hay necesidad de ambos, ¿es seguro eliminarContextLoaderListener
por qué estoy preguntando porque la aplicación está activa desde hace 7-8 meses? web.xml está aquí para su referencia.ContextLoaderListener
es opcional . Solo para hacer un punto aquí: puede iniciar una aplicación Spring sin configurarlaContextLoaderListener
, solo un mínimo básicoweb.xml
conDispatcherServlet
.Así es como se vería:
web.xml
Cree un archivo llamado
dispatcher-servlet.xml
y guárdelo debajoWEB-INF
. Como mencionamosindex.jsp
en la lista de bienvenida, agregue este archivo debajoWEB-INF
.dispatcher-servlet.xml
En el
dispatcher-servlet.xml
define tus frijoles:fuente
Para una aplicación Spring simple, no tiene que definir
ContextLoaderListener
en suweb.xml
; puedes poner todos tus archivos de configuración de Spring en<servlet>
:Para una aplicación Spring más compleja, donde tiene múltiples
DispatcherServlet
definidos, puede tener los archivos de configuración comunes de Spring que comparten todos losDispatcherServlet
definidos enContextLoaderListener
:Solo tenga en cuenta que
ContextLoaderListener
realiza el trabajo de inicialización real para el contexto de la aplicación raíz .Encontré que este artículo ayuda mucho: Spring MVC - Contexto de aplicación vs Contexto de aplicación web
fuente
El blog, " Propósito de ContextLoaderListener - Spring MVC " da una muy buena explicación.
Según esto, los contextos de aplicación son jerárquicos y, por lo tanto, el contexto de DispatcherSerlvet se convierte en hijo del contexto de ContextLoaderListener. Debido a lo cual, la tecnología que se utiliza en la capa del controlador (Struts o Spring MVC) puede ser independiente del contexto raíz creado ContextLoaderListener.
fuente
Cuando desee colocar su archivo Servlet en su ubicación personalizada o con un nombre personalizado, en lugar de la convención de nomenclatura
[servletname]-servlet.xml
y la ruta predeterminadasWeb-INF/
, puede usarContextLoaderListener
.fuente
ContextLoaderListner es un escucha de Servlet que carga todos los diferentes archivos de configuración (configuración de la capa de servicio, configuración de la capa de persistencia, etc.) en un contexto de aplicación de resorte único.
Esto ayuda a dividir las configuraciones de resorte en múltiples archivos XML.
Una vez que se cargan los archivos de contexto, Spring crea un objeto WebApplicationContext basado en la definición de bean y lo almacena en el ServletContext de su aplicación web.
fuente
Este oyente Bootstrap es para iniciar y cerrar la raíz de Spring WebApplicationContext. Como una aplicación web puede tener múltiples servlets de despacho y cada uno tiene su propio contexto de aplicación que contiene controladores, resolución de vista, asignaciones de manejador, etc. contexto de aplicación creado por servlets de despachador).
El segundo uso de este oyente es cuando desea utilizar la seguridad de primavera.
fuente
Contextos raíz e hijo Antes de seguir leyendo, comprenda que:
La primavera puede tener múltiples contextos a la vez. Uno de ellos será el contexto raíz, y todos los demás contextos serán contextos secundarios.
Todos los contextos secundarios pueden acceder a los beans definidos en el contexto raíz; pero lo contrario no es cierto. El contexto raíz no puede acceder a los contextos secundarios beans.
ApplicationContext:
applicationContext.xml es la configuración del contexto raíz para cada aplicación web. Spring carga el archivo applicationContext.xml y crea el ApplicationContext para toda la aplicación. Solo habrá un contexto de aplicación por aplicación web. Si no está declarando explícitamente el nombre del archivo de configuración de contexto en web.xml utilizando el parámetro contextConfigLocation, Spring buscará el applicationContext.xml en la carpeta WEB-INF y lanzará FileNotFoundException si no puede encontrar este archivo.
ContextLoaderListener Realiza el trabajo de inicialización real para el contexto de la aplicación raíz. Lee un parámetro de contexto "contextConfigLocation" y pasa su valor a la instancia de contexto, analizándolo en rutas de archivos potencialmente múltiples que pueden estar separadas por cualquier número de comas y espacios, por ejemplo, "WEB-INF / applicationContext1.xml, WEB-INF / applicationContext2.xml ". ContextLoaderListener es opcional. Solo para hacer un punto aquí: puede iniciar una aplicación Spring sin configurar ContextLoaderListener, solo un mínimo web.xml básico con DispatcherServlet.
DispatcherServlet DispatcherServlet es esencialmente un Servlet (extiende HttpServlet) cuyo propósito principal es manejar las solicitudes web entrantes que coinciden con el patrón de URL configurado. Se necesita un URI entrante y encuentra la combinación correcta de controlador y vista. Entonces es el controlador frontal.
Cuando define un DispatcherServlet en la configuración de primavera, proporciona un archivo XML con entradas de clases de controlador, asignaciones de vistas, etc. utilizando el atributo contextConfigLocation.
WebApplicationContext Además de ApplicationContext, puede haber múltiples WebApplicationContext en una sola aplicación web. En palabras simples, cada DispatcherServlet asociado con un solo WebApplicationContext. El archivo xxx-servlet.xml es específico del DispatcherServlet y una aplicación web puede tener más de un DispatcherServlet configurado para manejar las solicitudes. En tales escenarios, cada DispatcherServlet tendría un xxx-servlet.xml configurado por separado. Pero applicationContext.xml será común para todos los archivos de configuración de servlet. Spring cargará por defecto el archivo llamado "xxx-servlet.xml" de su carpeta web-INF webapps donde xxx es el nombre del servlet en web.xml. Si desea cambiar el nombre de ese nombre de archivo o cambiar la ubicación, agregue initi-param con contextConfigLocation como nombre de parámetro.
Comparación y relación entre ellos:
ContextLoaderListener vs DispatcherServlet
ContextLoaderListener crea el contexto de la aplicación raíz. Las entradas de DispatcherServlet crean un contexto de aplicación hijo por entrada de servlet. Los contextos secundarios pueden acceder a beans definidos en el contexto raíz. Los beans en el contexto raíz no pueden acceder a los beans en contextos secundarios (directamente). Todos los contextos se agregan a ServletContext. Puede acceder al contexto raíz utilizando la clase WebApplicationContextUtils.
Después de leer la documentación de Spring, lo siguiente es entender:
a) Los contextos de aplicación son jerárquicos y también lo son los WebApplicationContexts. Consulte la documentación aquí.
b) ContextLoaderListener crea un contexto de aplicación web raíz para la aplicación web y lo coloca en el contexto de Servlet. Este contexto se puede utilizar para cargar y descargar los beans gestionados por resorte independientemente de qué tecnología se esté utilizando en la capa del controlador (Struts o Spring MVC).
c) DispatcherServlet crea su propio WebApplicationContext y los manejadores / controladores / resolutores de vista son administrados por este contexto.
d) Cuando ContextLoaderListener se usa junto con DispatcherServlet, se crea un contexto de aplicación web raíz primero como se dijo anteriormente y DispatcherSerlvet también crea un contexto hijo y se adjunta al contexto de aplicación raíz. Consulte la documentación aquí.
Cuando estamos trabajando con Spring MVC y también estamos usando Spring en la capa de servicios, proporcionamos dos contextos de aplicación. El primero se configura con ContextLoaderListener y el otro con DispatcherServlet
En general, definirá todos los beans relacionados con MVC (controlador y vistas, etc.) en el contexto DispatcherServlet, y todos los beans transversales como seguridad, transacciones, servicios, etc. en el contexto raíz por ContextLoaderListener.
Consulte esto para obtener más detalles: https://siddharthnawani.blogspot.com/2019/10/contextloaderlistener-vs.html
fuente
Básicamente, puede aislar el contexto de la aplicación raíz y el contexto de la aplicación web utilizando ContextLoaderListner.
El archivo de configuración asignado con el parámetro de contexto se comportará como la configuración de contexto de la aplicación raíz. Y el archivo de configuración asignado con el servlet del despachador se comportará como el contexto de la aplicación web.
En cualquier aplicación web podemos tener múltiples servlets de despachador, por lo que múltiples contextos de aplicación web.
Pero en cualquier aplicación web podemos tener solo un contexto de aplicación raíz que se comparte con todos los contextos de aplicación web.
Deberíamos definir nuestros servicios, entidades, aspectos, etc. comunes en el contexto de la aplicación raíz. Y los controladores, interceptores, etc. están en el contexto relevante de la aplicación web.
Un ejemplo de web.xml es
Aquí la clase de configuración example.config.AppConfig se puede usar para configurar servicios, entidades, aspectos, etc. en el contexto de la aplicación raíz que se compartirá con todos los demás contextos de la aplicación web (por ejemplo, aquí tenemos dos clases de configuración del contexto de la aplicación web RestConfig y WebConfig)
PD: Aquí ContextLoaderListener es completamente opcional. Si no mencionamos ContextLoaderListener en web.xml aquí, AppConfig no funcionará. En ese caso, necesitamos configurar todos nuestros servicios y entidades en WebConfig y Rest Config.
fuente
Le dará un punto de enlace para colocar el código que desea ejecutar en el tiempo de implementación de la aplicación web
fuente
Clase de escucha: escucha un evento (p. Ej., Inicio / apagado del servidor)
ContextLoaderListener -
Los archivos de configuración se pueden proporcionar así en web.xml
fuente
En el contexto de Spring Framework, el propósito de ContextLoaderListener es cargar los otros beans en su aplicación, como los componentes de nivel medio y nivel de datos que controlan el back-end de la aplicación.
fuente
Su comprensión es correcta. Me pregunto por qué no ves ninguna ventaja en ContextLoaderListener. Por ejemplo, necesita construir una fábrica de sesiones (para administrar la base de datos). Esta operación puede llevar algo de tiempo, por lo que es mejor hacerlo al inicio. Por supuesto, puede hacerlo con servlets init u otra cosa, pero la ventaja del enfoque de Spring es que realiza la configuración sin escribir código.
fuente
Si escribimos web.xml sin ContextLoaderListener, entonces no podemos dar el atletismo usando customAuthenticationProvider en seguridad de primavera. Debido a que DispatcherServelet es el contexto secundario de ContextLoaderListener, customAuthenticationProvider es la parte de parentContext que es ContextLoaderListener. Por lo tanto, el contexto primario no puede tener las dependencias del contexto secundario. Por lo tanto, se recomienda escribir spring-context.xml en contextparam en lugar de escribirlo en initparam.
fuente
Creo que su uso real se produce cuando desea tener más de un archivo de configuración o tiene un archivo xyz.xml en lugar de applicationcontext.xml, por ejemplo
<context-param><param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/training-service.xml, /WEB-INF/training-data.xml</param-value> </context-param>
Otro enfoque para ContextLoaderListener es usar ContextLoaderServlet como se muestra a continuación
<servlet> <servlet-name>context</servlet-name> <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet>
fuente