在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
的目的有两个:
-
将
ApplicationContext
的生命周期与ServletContext
和 -
自动创build
ApplicationContext
,所以你不需要写明确的代码来创build它 – 这是一个方便的function。
关于ContextLoaderListener
另一个方便之处在于它创build了一个WebApplicationContext
, WebApplicationContext
通过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.xml
和Web-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 –
- 在服务器启动/closures期间进行监听
- 将Springconfiguration文件作为input,并根据configuration创buildbean,并将其准备就绪(在closures期间破坏bean)
-
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的应用程序上下文)。
这个监听器的第二次使用是当你想使用弹簧安全。