我正在学习在我的项目中使用的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 回答
你的理解是正确的 .
ApplicationContext
是您的Spring bean所在的地方 .ContextLoaderListener
的目的是双重的:将
ApplicationContext
的生命周期与ServletContext
的生命周期联系起来自动创建
ApplicationContext
,因此您不需要't have to write explicit code to do create it - it'的便利功能 .关于
ContextLoaderListener
的另一个方便之处是它创建了一个WebApplicationContext
和WebApplicationContext
提供了对ServletContext
通过ServletContextAware bean和getServletContext
方法的访问 .ContextLoaderListener
是可选的 . 只是为了说明一点:你可以在没有配置ContextLoaderListener
的情况下启动Spring应用程序,只需一个基本的最小web.xml
和DispatcherServlet
.这是它的样子:
web.xml
创建一个名为
dispatcher-servlet.xml
的文件并将其存储在WEB-INF
下 . 由于我们在欢迎列表中提到index.jsp
,请在WEB-INF
下添加此文件 .dispatcher-servlet.xml
在
dispatcher-servlet.xml
中定义你的bean:对于一个简单的Spring应用程序,您不必在
web.xml
中定义ContextLoaderListener
;您可以将所有Spring配置文件放在<servlet>
中:对于更复杂的Spring应用程序,您定义了多个
DispatcherServlet
,您可以拥有ContextLoaderListener
中定义的所有DispatcherServlet
共享的公共Spring配置文件:请记住,
ContextLoaderListener
执行 root 应用程序上下文的实际初始化工作 .我发现这篇文章有很多帮助:Spring MVC – Application Context vs Web Application Context
博客“Purpose of ContextLoaderListener – Spring MVC”给出了非常好的解释 .
根据它,Application-Contexts是分层的,因此DispatcherSerlvet的上下文成为ContextLoaderListener上下文的子代 . 因此,在控制器层(Struts或Spring MVC)中使用的技术可以独立于根上下文创建的ContextLoaderListener .
如果要将Servlet文件放在自定义位置或使用自定义名称,而不是默认命名约定
[servletname]-servlet.xml
和Web-INF/
下的路径,则可以使用ContextLoaderListener
.ContextLoaderListner是一个Servlet侦听器,它将所有不同的配置文件(服务层配置,持久层配置等)加载到单个spring应用程序上下文中 .
这有助于跨多个XML文件拆分 spring 配置 .
加载上下文文件后,Spring会根据bean定义创建一个WebApplicationContext对象,并将其存储在Web应用程序的ServletContext中 .
基本上,您可以使用ContextLoaderListner隔离根应用程序上下文和Web应用程序上下文 .
使用上下文参数映射的配置文件将表现为根应用程序上下文配置 . 与调度程序servlet映射的配置文件将表现得像Web应用程序上下文 .
在任何Web应用程序中,我们可能有多个调度程序servlet,因此有多个Web应用程序上下文 .
但是在任何Web应用程序中,我们可能只有一个与所有Web应用程序上下文共享的根应用程序上下文 .
我们应该在根应用程序上下文中定义我们的公共服务,实体,方面等 . 控制器,拦截器等都在相关的Web应用程序环境中 .
一个示例web.xml是
这里的config class example.config.AppConfig可用于在根应用程序中配置服务,实体,方面等将与所有其他Web应用程序上下文共享的上下文(例如,此处我们有两个Web应用程序上下文配置类RestConfig和WebConfig)
PS:这里ContextLoaderListener是完全可选的 . 如果我们在这里不提及web.xml中的ContextLoaderListener,AppConfig将无法工作 . 在这种情况下,我们需要在WebConfig和Rest Config中配置我们的所有服务和实体 .
此Bootstrap监听器将启动并关闭Spring的 root WebApplicationContext . 因为Web应用程序可以有多个调度程序servlet,每个都有自己的应用程序上下文,包含控制器,视图解析程序,处理程序映射等 . 但是您可能希望在根应用程序上下文中使用服务bean,DAO bean并希望在所有子应用程序上下文中使用(调度程序servlet创建的应用程序上下文 .
第二次使用此侦听器是您希望使用spring安全性的时候 .
它将为您提供一些钩子来放置您希望在Web应用程序部署时执行的一些代码
你的理解是正确的 . 我想知道你为什么在ContextLoaderListener中没有看到任何优点 . 例如,您需要构建会话工厂(以管理数据库) . 此操作可能需要一些时间,因此最好在启动时执行此操作 . 当然你可以用init servlet或其他东西来做,但Spring的方法的优点是你可以在不编写代码的情况下进行配置 .
如果我们在没有ContextLoaderListener的情况下编写web.xml,那么我们无法在spring security中使用customAuthenticationProvider进行athuntication . 因为DispatcherServelet是ContextLoaderListener的子上下文,所以customAuthenticationProvider是parentContext的一部分,它是ContextLoaderListener . 所以父Context不能具有子上下文的依赖关系 . 因此,最好在contextparam中编写spring-context.xml,而不是在initparam中编写它 .
我相信它的真正用途是当你想拥有多个配置文件或者你有 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>
监听器类 - 监听事件(例如,服务器启动/关闭)
ContextLoaderListener -
在服务器启动/关闭期间侦听
将Spring配置文件作为输入并根据配置创建bean并使其准备就绪(在关闭期间销毁bean)
可以在web.xml中像这样提供配置文件
在spring框架的上下文中, ContextLoaderListener 的目的是在应用程序中加载其他bean,例如驱动应用程序后端的中间层和数据层组件 .