在Spring中的ContextLoaderListener的作用/目的?

我正在学习我的项目中使用的Spring框架 。 我在我的web.xml文件中find了ContextLoaderListener条目。 但无法弄清楚它如何帮助开发人员?

ContextLoaderListener的官方文档中说它是启动WebApplicationContext 。 关于WebApplicationContext JavaDocs说:

提供Web应用程序configuration的接口。

但是我无法理解我在用内部初始化WebApplicationContext的 ContextLoaderListener实现了什么?

根据我的理解ContextLoaderListener读取Springconfiguration文件(对web.xml中的contextConfigLocation赋予值),parsing它并加载在该configuration文件中定义的单例bean 。 同样,当我们要加载原型bean时 ,我们将使用相同的web应用上下文来加载它。 所以我们用ContextLoaderListener初始化了web应用程序,以便我们提前读取/parsing/validationconfiguration文件,无论何时我们要注入依赖关系,我们都可以毫不拖延地做到这一点。 这种理解是否正确?

你的理解是正确的。 ApplicationContext是Spring bean所在的地方。 ContextLoaderListener的目的有两个:

  1. ApplicationContext的生命周期与ServletContext

  2. 自动创buildApplicationContext ,所以你不需要写明确的代码来创build它 – 这是一个方便的function。

关于ContextLoaderListener另一个方便之处在于它创build了一个WebApplicationContextWebApplicationContext通过ServletContextAware bean和getServletContext方法提供对ServletContext访问。

ContextLoaderListener可选的 。 为了说明问题,您可以启动Spring应用程序,而无需configurationContextLoaderListener ,只需使用DispatcherServlet即可创build基本的最小web.xml

这是它的样子:

web.xml中

 <?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation=" http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5"> <display-name>Some Minimal Webapp</display-name> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class> org.springframework.web.servlet.DispatcherServlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping> </web-app> 

创build一个名为dispatcher-servlet.xml的文件并将其存储在WEB-INF 。 由于我们在欢迎列表中提到了index.jsp ,所以在WEB-INF下添加这个文件。

调度员servlet.xml中

dispatcher-servlet.xml定义你的bean:

 <?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:p="http://www.springframework.org/schema/p" 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.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <bean id="bean1"> ... </bean> <bean id="bean2"> ... </bean> <context:component-scan base-package="com.example" /> <!-- Import your other configuration files too --> <import resource="other-configs.xml"/> <import resource="some-other-config.xml"/> <!-- View Resolver --> <bean id="viewResolver" class="org.springframework.web.servlet.view.UrlBasedViewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> <property name="prefix" value="/WEB-INF/jsp/" /> <property name="suffix" value=".jsp" /> </bean> </beans> 

对于一个简单的Spring应用程序,您不必在web.xml定义ContextLoaderListener ; 你可以把所有的Springconfiguration文件放在<servlet>

 <servlet> <servlet-name>hello</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring/mvc-core-config.xml, classpath:spring/business-config.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> 

对于更复杂的Spring应用程序,如果您定义了多个DispatcherServlet ,则可以使用ContextLoaderListener定义的所有DispatcherServlet共享的公共Springconfiguration文件:

 <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring/common-config.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <servlet> <servlet-name>mvc1</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring/mvc1-config.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet> <servlet-name>mvc2</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring/mvc2-config.xmll</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> 

请记住, ContextLoaderListener执行应用程序上下文的实际初始化工作。

我发现这篇文章有很多帮助: Spring MVC – 应用程序上下文与Web应用程序上下文

博客“ ContextLoaderListener的用途 – Spring MVC ”给出了很好的解释。

据此,应用程序上下文是分层的,因此DispatcherSerlvet的上下文成为ContextLoaderListener上下文的子元素。 由此,在控制器层(Struts或Spring MVC)中使用的技术可独立于创buildContextLoaderListener的根上下文。

当你想把你的Servlet文件放到你的自定义位置或自定义名称中,而不是默认的命名约定[servletname]-servlet.xmlWeb-INF/下的path时,你可以使用ContextLoaderListener

基本上你可以使用ContextLoaderListner来隔离你的根应用上下文和web应用上下文。

使用上下文参数映射的configuration文件将performance为根应用程序上下文configuration。 与调度程序servlet映射的configuration文件将performance得像Web应用程序上下文。

在任何Web应用程序中,我们可能有多个调度程序servlet,因此有多个Web应用程序上下文。

但是在任何Web应用程序中,我们可能只有一个与所有Web应用程序上下文共享的根应用程序上下文。

我们应该在根应用上下文中定义我们的通用服务,实体,方面等。 而控制器,拦截器等都在相关的web应用上下文中。

示例web.xml是

 <!-- language: xml --> <web-app> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextClass</param-name> <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value> </context-param> <context-param> <param-name>contextConfigLocation</param-name> <param-value>example.config.AppConfig</param-value> </context-param> <servlet> <servlet-name>restEntryPoint</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextClass</param-name> <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value> </init-param> <init-param> <param-name>contextConfigLocation</param-name> <param-value>example.config.RestConfig</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>restEntryPoint</servlet-name> <url-pattern>/rest/*</url-pattern> </servlet-mapping> <servlet> <servlet-name>webEntryPoint</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextClass</param-name> <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value> </init-param> <init-param> <param-name>contextConfigLocation</param-name> <param-value>example.config.WebConfig</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>webEntryPoint</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping> </web-app> 

这里可以使用config类的example.config.AppConfig在根应用程序上下文中configuration服务,实体,方面等,这些应用程序上下文将与所有其他Web应用程序上下文共享(例如,在这里我们有两个Web应用程序上下文configuration类RestConfig和WebConfig)

PS:这里ContextLoaderListener是完全可选的。 如果我们不在这里提到web.xml中的ContextLoaderListener,AppConfig将不起作用。 在这种情况下,我们需要在WebConfig和Rest Config中configuration我们所有的服务和实体。

它会给你点钩子,把一些代码,你希望在Web应用程序部署时执行

你的理解是正确的。 我不知道为什么你在ContextLoaderListener中看不到任何优势。 例如,你需要build立一个会话工厂(来pipe理数据库)。 此操作可能需要一些时间,所以最好在启动时进行。 当然,你可以用init servlet或其他的方式来做,但是Spring的方法的优点是你不用编写代码就可以进行configuration。

如果我们在没有ContextLoaderListener的情况下编写web.xml,那么我们就不能在spring security中使用customAuthenticationProvider进行authentication。 因为DispatcherServelet是ContextLoaderListener的子上下文,所以customAuthenticationProvider是ContextContainer的parentContext的一部分。 所以父上下文不能有子上下文的依赖关系。 所以最好的做法是在contextparam中编写spring-context.xml,而不是写入initparam。

我相信它的真正用处是当你想有多个configuration文件,或者你有xyz.xml文件而不是applicationcontext.xml,例如

<context-param><param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/training-service.xml, /WEB-INF/training-data.xml</param-value> </context-param>

ContextLoaderListener的另一种方法是使用如下的ContextLoaderServlet

<servlet> <servlet-name>context</servlet-name> <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet>

监听器类 – 监听事件(例如服务器启动/closures)

ContextLoaderListener –

  1. 在服务器启动/closures期间进行监听
  2. 将Springconfiguration文件作为input,并根据configuration创buildbean,并将其准备就绪(在closures期间破坏bean)
  3. configuration文件可以在web.xml中像这样提供

     <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/dispatcher-servlet.xml</param-value> 

ContextLoaderListner是一个Servlet侦听器,它将所有不同的configuration文件(服务层configuration,持久层configuration等)加载到单个spring应用程序上下文中。

这有助于跨多个XML文件拆分弹簧configuration。

一旦加载了上下文文件,Spring将创build一个基于bean定义的WebApplicationContext对象,并将其存储在Web应用程序的ServletContext中。

在Spring框架的上下文中, ContextLoaderListener的目的是加载应用程序中的其他bean,例如驱动应用程序后端的中间层和数据层组件。

在这里输入图像描述 这个Bootstrap监听器是启动并closuresSpring的 WebApplicationContext。 作为一个Web应用程序可以有多个调度程序servlet,每个都有自己的应用程序上下文包含控制器,视图parsing器,处理程序映射等。但您可能希望有服务bean,根应用程序上下文中的DAO bean,并希望在所有子应用程序上下文由调度程序servlet创build的应用程序上下文)。

这个监听器的第二次使用是当你想使用弹簧安全。