首页 文章

ContextLoaderListener在Spring中的角色/目的?

提问于
浏览
156

我正在学习在我的项目中使用的Spring Framework . 我在web.xml文件中找到了 ContextLoaderListener 条目 . 但无法弄清楚它对开发人员有何帮助?

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

用于为Web应用程序提供配置的界面 .

但我无法理解我在ContextLoaderListener中实现了什么,它在内部初始化WebApplicationContext?

As per my understanding ,ContextLoaderListener读取Spring配置文件(使用web.xml中的contextConfigLocation给出的值),解析它并加载该配置文件中定义的单例bean . 类似地,当我们想要加载原型bean时,我们将使用相同的webapplication上下文来加载它 . 因此,我们使用ContextLoaderListener初始化web应用程序,以便我们提前读取/解析/验证配置文件,每当我们想要注入依赖项时,我们都可以毫不拖延地直接执行它 . 这种理解是否正确?

14 回答

  • 23

    你的理解是正确的 . ApplicationContext 是您的Spring bean所在的地方 . ContextLoaderListener 的目的是双重的:

    • ApplicationContext 的生命周期与 ServletContext 的生命周期联系起来

    • 自动创建 ApplicationContext ,因此您不需要't have to write explicit code to do create it - it'的便利功能 .

    关于 ContextLoaderListener 的另一个方便之处是它创建了一个 WebApplicationContextWebApplicationContext 提供了对 ServletContext 通过ServletContextAware bean和 getServletContext 方法的访问 .

  • 2

    ContextLoaderListener 是可选的 . 只是为了说明一点:你可以在没有配置 ContextLoaderListener 的情况下启动Spring应用程序,只需一个基本的最小 web.xmlDispatcherServlet .

    这是它的样子:

    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>
    

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

    dispatcher-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>
    
  • 0

    对于一个简单的Spring应用程序,您不必在 web.xml 中定义 ContextLoaderListener ;您可以将所有Spring配置文件放在 <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 共享的公共Spring配置文件:

    <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 执行 root 应用程序上下文的实际初始化工作 .

    我发现这篇文章有很多帮助:Spring MVC – Application Context vs Web Application Context

  • 39

    博客“Purpose of ContextLoaderListener – Spring MVC”给出了非常好的解释 .

    根据它,Application-Contexts是分层的,因此DispatcherSerlvet的上下文成为ContextLoaderListener上下文的子代 . 因此,在控制器层(Struts或Spring MVC)中使用的技术可以独立于根上下文创建的ContextLoaderListener .

  • 0

    如果要将Servlet文件放在自定义位置或使用自定义名称,而不是默认命名约定 [servletname]-servlet.xmlWeb-INF/ 下的路径,则可以使用 ContextLoaderListener .

  • 10

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

    这有助于跨多个XML文件拆分 spring 配置 .

    加载上下文文件后,Spring会根据bean定义创建一个WebApplicationContext对象,并将其存储在Web应用程序的ServletContext中 .

  • 1

    基本上,您可以使用ContextLoaderListner隔离根应用程序上下文和Web应用程序上下文 .

    使用上下文参数映射的配置文件将表现为根应用程序上下文配置 . 与调度程序servlet映射的配置文件将表现得像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 class example.config.AppConfig可用于在根应用程序中配置服务,实体,方面等将与所有其他Web应用程序上下文共享的上下文(例如,此处我们有两个Web应用程序上下文配置类RestConfig和WebConfig)

    PS:这里ContextLoaderListener是完全可选的 . 如果我们在这里不提及web.xml中的ContextLoaderListener,AppConfig将无法工作 . 在这种情况下,我们需要在WebConfig和Rest Config中配置我们的所有服务和实体 .

  • 3

    enter image description here
    此Bootstrap监听器将启动并关闭Spring的 root WebApplicationContext . 因为Web应用程序可以有多个调度程序servlet,每个都有自己的应用程序上下文,包含控制器,视图解析程序,处理程序映射等 . 但是您可能希望在根应用程序上下文中使用服务bean,DAO bean并希望在所有子应用程序上下文中使用(调度程序servlet创建的应用程序上下文 .

    第二次使用此侦听器是您希望使用spring安全性的时候 .

  • 0

    它将为您提供一些钩子来放置您希望在Web应用程序部署时执行的一些代码

  • 99

    你的理解是正确的 . 我想知道你为什么在ContextLoaderListener中没有看到任何优点 . 例如,您需要构建会话工厂(以管理数据库) . 此操作可能需要一些时间,因此最好在启动时执行此操作 . 当然你可以用init servlet或其他东西来做,但Spring的方法的优点是你可以在不编写代码的情况下进行配置 .

  • 0

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

  • 3

    我相信它的真正用途是当你想拥有多个配置文件或者你有 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>

  • 2

    监听器类 - 监听事件(例如,服务器启动/关闭)

    ContextLoaderListener -

    • 在服务器启动/关闭期间侦听

    • 将Spring配置文件作为输入并根据配置创建bean并使其准备就绪(在关闭期间销毁bean)

    • 可以在web.xml中像这样提供配置文件

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

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

相关问题