ContextLoaderListener在Spring中的角色/目的?

时间:2012-08-05 09:30:54

标签: java spring web-applications

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

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

  

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


但是我无法理解我使用 ContextLoaderListener 在内部初始化 WebApplicationContext 所实现的目标?

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

15 个答案:

答案 0 :(得分:100)

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

  1. ApplicationContext的生命周期与ServletContext

  2. 的生命周期联系起来
  3. 自动创建ApplicationContext,因此您不必编写显式代码来创建它 - 它是一个方便的功能。

  4. 关于ContextLoaderListener的另一个方便之处是,它创建了WebApplicationContextWebApplicationContext提供了ServletContext来自ServletContextAware bean和{{1}的访问权限方法。

答案 1 :(得分:40)

ContextLoaderListener 可选。只是为了说明一点:你可以在没有配置ContextLoaderListener的情况下启动Spring应用程序,只需要web.xml DispatcherServlet的基本<?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>

以下是它的样子:

<强>的web.xml

dispatcher-servlet.xml

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

<强>调度-servlet.xml中

<?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> 定义你的bean:

{{1}}

答案 2 :(得分:23)

对于简单的Spring应用程序,您不必在/product/3中定义/product/foo;您可以将所有Spring配置文件放在ContextLoaderListener

web.xml

对于更复杂的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> 中定义的所有DispatcherServlet共享的公共Spring配置文件: / p>

DispatcherServlet

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

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

答案 3 :(得分:10)

博客&#34; Purpose of ContextLoaderListener – Spring MVC&#34;给出了很好的解释。

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

答案 4 :(得分:3)

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

答案 5 :(得分:3)

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

这有助于在多个XML文件之间拆分弹簧配置。

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

答案 6 :(得分:2)

基本上,您可以使用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中配置我们的所有服务和实体。

答案 7 :(得分:2)

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

第二次使用此侦听器是您希望使用spring security。

答案 8 :(得分:1)

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

答案 9 :(得分:0)

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

答案 10 :(得分:0)

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

答案 11 :(得分:0)

我相信当你想要拥有多个配置文件或者你有 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>

答案 12 :(得分:0)

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

ContextLoaderListener -

  1. 在服务器启动/关闭期间侦听
  2. 将Spring配置文件作为输入并按配置创建bean并使其准备就绪(在关闭期间销毁bean)
  3. 可以在web.xml中提供配置文件

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

答案 13 :(得分:0)

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

答案 14 :(得分:0)

根和子上下文 在进一步阅读之前,请了解–

Spring一次可以有多个上下文。其中之一将是根上下文,而所有其他上下文将是子上下文。

所有子上下文都可以访问在根上下文中定义的bean;但事实并非如此。根上下文无法访问子上下文Bean。

ApplicationContext:

applicationContext.xml是每个Web应用程序的根上下文配置。 Spring加载applicationContext.xml文件并为整个应用程序创建ApplicationContext。 每个Web应用程序只有一个应用程序上下文。 如果没有使用contextConfigLocation参数在web.xml中明确声明上下文配置文件名,Spring将在WEB-INF文件夹下搜索applicationContext.xml,如果找不到该文件,则抛出FileNotFoundException。

ContextLoaderListener 对根应用程序上下文执行实际的初始化工作。 读取“ contextConfigLocation”上下文参数,并将其值传递到上下文实例,将其解析为可能由多个逗号和空格分隔的多个文件路径,例如“ WEB-INF / applicationContext1.xml,WEB-INF / applicationContext2.xml”。 ContextLoaderListener是可选的。此处仅说明一点:您无需配置ContextLoaderListener即可启动Spring应用程序,而仅使用DispatcherServlet配置基本的web.xml。

DispatcherServlet DispatcherServlet本质上是一个Servlet(它扩展了HttpServlet),其主要目的是处理与配置的URL模式匹配的传入Web请求。它采用传入的URI并找到控制器和视图的正确组合。所以是前端控制器。

当您在春季配置中定义DispatcherServlet时,您可以使用contextConfigLocation属性为XML文件提供控制器类,视图映射等条目。

WebApplicationContext 除了ApplicationContext,在一个Web应用程序中可以有多个WebApplicationContext。 简单来说,每个DispatcherServlet与单个WebApplicationContext相关联。 xxx-servlet.xml文件特定于DispatcherServlet,并且一个Web应用程序可以配置多个DispatcherServlet来处理请求。 在这种情况下,每个DispatcherServlet都将配置一个单独的xxx-servlet.xml。但是,applicationContext.xml对于所有servlet配置文件都是通用的。 默认情况下,Spring将从您的webapps WEB-INF文件夹中加载名为“ xxx-servlet.xml”的文件,其中xxx是web.xml中的servlet名称。 如果要更改该文件名的名称或更改位置,请添加带有contextConfigLocation作为参数名称的initi-param。

它们之间的比较和关系:

ContextLoaderListener与DispatcherServlet

ContextLoaderListener创建根应用程序上下文。 DispatcherServlet条目为每个Servlet条目创建一个子应用程序上下文。 子上下文可以访问在根上下文中定义的bean。 根上下文中的Bean无法(直接)访问子上下文中的Bean。 所有上下文都添加到ServletContext中。 您可以使用WebApplicationContextUtils类访问根上下文。

在阅读了Spring文档之后,您将了解以下内容:

a)应用程序上下文是层次结构,WebApplicationContexts也是如此。请参阅此处的文档。

b)ContextLoaderListener为Web应用程序创建一个根Web应用程序上下文,并将其放在ServletContext中。无论在控制器层中使用哪种技术(Struts或Spring MVC),都可以使用此上下文加载和卸载Spring管理的bean。

c)DispatcherServlet创建自己的WebApplicationContext,并且处理程序/控制器/视图解析器由该上下文管理。

d)当ContextLoaderListener与DispatcherServlet一起使用时,首先创建一个根Web应用程序上下文,如先前所述,并且一个子上下文也由DispatcherSerlvet创建,并附加到根应用程序上下文。请参阅此处的文档。

当我们使用Spring MVC并在服务层中使用Spring时,我们提供了两个应用程序上下文。第一个使用ContextLoaderListener配置,另一个使用DispatcherServlet

通常,您将在ContextLoaderListener中在DispatcherServlet上下文中定义所有与MVC相关的bean(控制器和视图等),并在根上下文中定义所有跨领域的bean(例如安全性,事务,服务等)。

有关更多详细信息,请参考: https://siddharthnawani.blogspot.com/2019/10/contextloaderlistener-vs.html