必威体育Betway必威体育官网
当前位置:首页 > IT技术

ContextLoaderListener介绍

时间:2019-08-11 10:44:17来源:IT技术作者:seo实验室小编阅读:90次「手机版」
 

contextloaderlistener

在给新同事培训Spring MVC时,有人问:可以不配置contextloaderlistener吗

所谓ContextLoaderListener,就是在web部署描述符即web.xml里面经常配置的一个监听器,如下

[html] view plain copy

  1. <listener>  
  2.     <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
  3. </listener>  

那么配合它一起使用的,经常是context-param,用来指定Spring要加载的配置文件,比如

[html] view plain copy

  1. <context-param>  
  2.     <param-name>contextconfiglocation</param-name>  
  3.     <param-value>/WEB-INF/teach-servlet.xml</param-value>  
  4. </context-param>  
  5.   
  6. <!-- Spring MVC -->  
  7. <servlet>  
  8.     <servlet-name>teach</servlet-name>  
  9.     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
  10.     <load-on-startup>1</load-on-startup>  
  11. </servlet>  
  12. <servlet-mAPPing>  
  13.     <servlet-name>teach</servlet-name>  
  14.     <url-pattern>*.action</url-pattern>  
  15. </servlet-mapping>  

上面两段就是在使用Spring MVC时,常用的配置,DispatcherServlet作为Spring MVC控制器的核心调度器

至于 teach-servlet.xml 就是配置一些Spring MVC需要使用的视图解析器等等

那么问题是:listener节点可以不配置吗?答案是肯定的:可以不做任何配置!

查看了ContextLoaderListener源代码,发现它继承自ContextLoader,并且实现ServletContextListener接口

肯定得实现这个接口了,不然怎么作为Servlet的监听器呢。。。

ContextLoaderListener 源代码很简单,核心是实现了 ServletContextListener 的contextInitialized和contextDestroyed方法

我们看下类图结构,只列出一部分属性和方法

因为 contextInitialized和contextDestroyed 方法分别调用了 ContextLoader里面的initwebapplicationContext和closeWebApplicationContext方法

所以核心最终还是 ContextLoader 实现了这个监听器,那这个监听器实现了什么功能呢,我们发现有两个重要属性

contextConfigLocation:即在web.xml里面指定的配置文件所在目录,如果不指定,Spring 会加载WEB_INF目录下,符合 *Context.xml 或 spring*.xml 规则的文件

currentContextPerThread:保存了当前WebApplicationContext

其实监听器的加载过程可以描述为:

先判WebApplicationContext是否已存在,不存在的话则初始化一个XmlWebApplicationContext(WebApplicationContext的子类),并把该实例put到 currentContextPerThread 中。而初始化 XmlWebApplicationContext 时,就跟我们使用 new ClassPathXmlApplicationContext(contextConfigLocation)一样

将我们配置的各种bean都添加到XmlWebApplicationContext中,所以我们知道 ApplicationContext 提供各种 getBean的方法。。。

并且可以发现 ContextLoader还提供了获取当前 WebApplicationContext的静态方法:之所以能获取,是因为initWebApplicationContext初始化方法把创建的XmlWebApplicationContext 塞到了 currentContextPerThread 中

说了一堆,跟Spring MVC 不配置ContextLoaderListener有什么关系呢。。。

因为 ContextLoaderListener 本质上是创建了一个 WebApplicationContext ,所以你的项目里面,如果不使用 WebApplicationContext 就可以不配置该节点。

那么只要做这种配置也是可以的:

[html] view plain copy

  1. <!-- Spring MVC -->  
  2.     <servlet>  
  3.         <servlet-name>teach</servlet-name>  
  4.         <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>  
  5.         <init-param>  
  6.             <param-name>contextConfigLocation</param-name>  
  7.             <param-value>/WEB-INF/teach-servlet.xml</param-value>  
  8.         </init-param>  
  9.         <load-on-startup>1</load-on-startup>  
  10.     </servlet>  
  11.     <servlet-mapping>  
  12.         <servlet-name>teach</servlet-name>  
  13.         <url-pattern>*.action</url-pattern>  
  14.     </servlet-mapping>  

发现Spring MVC 所需的配置文件不使用context-param节点指定,直接在DispatcherServlet里面配置即可

注意:这种情况下,你的应用程序是无法使用WebApplicationContext的

正常情况下,都会配置ContextLoaderListener,因为我们知道Spring IOC的两种实现

基础的就是BeanFactory,高级的就是ApplicationContext,除非在资源非常有限的情况下,才使用BeanFactory

否则都使用ApplicationContext,而WebApplicationContext就是其中的一种高级实现,它能提供很多有用的方法

那么在应用程序如何获取 WebApplicationContext 呢,有多种方式,最简单的就是

[java] view plain copy

  1. WebApplicationContext wac = ContextLoader.getCurrentWebApplicationContext();  

这个很熟悉了吧,刚才提到了,当前应用的WebApplicationContext就保存在 ContextLoader的currentContextPerThread属性当中

还有基于ServletContext上下文获取的方式

[java] view plain copy

  1. ServletContext sc = request.getsession().getServletContext();  
  2. ApplicationContext ac1 = WebApplicationContextUtils.getrequiredWebApplicationContext(sc);  
  3. ApplicationContext ac2 = WebApplicationContextUtils.getWebApplicationContext(sc);  
  4. WebApplicationContext wac1 = (WebApplicationContext) sc.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);  

还有一些更合适的,基于Spring提供的抽象类或者接口,在初始化Bean时注入ApplicationContext

继承自抽象类ApplicationObjectSupport

说明:抽象类ApplicationObjectSupport提供getApplicationContext()方法,可以方便的获取到ApplicationContext。

Spring初始化时,会通过该抽象类的setApplicationContext(ApplicationContext context)方法将ApplicationContext 对象注入。

继承自抽象类WebApplicationObjectSupport

说明:类似上面方法,调用getWebApplicationContext()获取WebApplicationContext

实现接口ApplicationContextAware

说明:实现该接口的setApplicationContext(ApplicationContext context)方法,并保存ApplicationContext 对象。

Spring初始化时,会通过该方法将ApplicationContext对象注入。

相关阅读

ContextLoaderListener与DispatcherServlet

在基于XML的Spring MVC配置中,您必须在web.xml文件中看到两个声明,即ContextLoaderListener和DispatcherServlet。让我们试着理解他

ContextLoaderListener与RequestContextListener的对

ContextLoaderListener与RequestContextListener(1)ContextLoaderListenerContextLoaderListenerextends ContextLoader implements

分享到:

栏目导航

推荐阅读

热门阅读