zoukankan      html  css  js  c++  java
  • Spring源码情操陶冶-ContextLoaderListener

    前言:通过实例结合源码的方式解读,其中涉及到的文件来自于博主的Github毕设项目wxServer
    Note: Springboot应用不在本文章讨论范围

    web.xml中启用Spring

    在一般的web应用程序,我们倘若用到Spring的话,需要在web.xml中配置以下的信息来使一些容器,例如TomcatJetty等来加载Spring

      <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:com/du/wx/resources/spring/springContext.xml</param-value>
      </context-param>
      <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
      </listener>
    

    Spring主要通过ContextLoaderListener类在应用启动时加载其服务

    ContextLoaderListener的官方注释

    查看某个类的重要功能最好是观察其的注释,ContextLoaderLinstener官方注释如下:

      //父级启动类,可用ContextLoader启动和ContextCleanupListener来关闭Spring的根web应用上下文
      Bootstrap listener to start up and shut down Spring's root {@link WebApplicationContext}.
      Simply delegates to {@link ContextLoader} as well as to {@link ContextCleanupListener}.
     
      //这里给出了提示,如果需要用到自定义log4j的配置的话,则ContextListener需要在Log4jConfigListener之后
      <p>This listener should be registered after {@link org.springframework.web.util.Log4jConfigListener}
      in {@code web.xml}, if the latter is used.
     //从Spring3.1之后,注入根web应用上下文可通过 WebApplicationInitializer,容器在启动会加载此接口,但是有个要求是容器的Servlet版本必须是3.0+,对Tomcat来说必须是7.0.15版本以上
      <p>As of Spring 3.1, {@code ContextLoaderListener} supports injecting the root web
      application context via the {@link #ContextLoaderListener(WebApplicationContext)}
      constructor, allowing for programmatic configuration in Servlet 3.0+ environments.
      See {@link org.springframework.web.WebApplicationInitializer} for usage examples.
     
      @author Juergen Hoeller
      @author Chris Beams
      @since 17.02.2003
      @see #setContextInitializers
      @see org.springframework.web.WebApplicationInitializer
      @see org.springframework.web.util.Log4jConfigListener
    

    重要的批注都在新增的注释上,并且我们可以发现,web.xml中的listener节点具有代码逻辑上的先写先加载的特点。

    特别需要注意的是如果用户需要用到Log4jConfigListener的话,则必须写在ContextLoaderListener的前面

    ContextLoaderListener结构

    public class ContextLoaderListener extends ContextLoader implements ServletContextListener{}
    

    最应该关注的是ServletContextListenr接口,我们应该知道实现此接口的类会在应用启动的时候,自动的调用其接口方法contextInitialized(ServletContextEvent event);
    关闭应用时候则会调用其另外一个接口方法contextDestroyed(ServletContextEvent evet)用来关闭web上下文信息。

    • 初始化
      public void contextInitialized(ServletContextEvent event) {
      	//调用的是父类ContextLoader的方法,看出来这是启动的关键
      	initWebApplicationContext(event.getServletContext());
      }
      
    • 关闭
      	//与初始化相对
      	closeWebApplicationContext(event.getServletContext());
      	//使用ContextCleanupLister监听类来销毁ServletContext的springwork属性信息
      	ContextCleanupListener.cleanupAttributes(event.getServletContext());
      
      这里我们简单的看下销毁属性的代码方法
      Enumeration<String> attrNames = sc.getAttributeNames();
      	while (attrNames.hasMoreElements()) {
      		String attrName = attrNames.nextElement();
      		//筛选出专属spring的属性
      		if (attrName.startsWith("org.springframework.")) {
      			Object attrValue = sc.getAttribute(attrName);
      			//基本WebApplication都实现了DisposableBean接口,表明所有的Bean都是可以释放的
      			if (attrValue instanceof DisposableBean) {
      				try {
      					((DisposableBean) attrValue).destroy();
      				}
      				catch (Throwable ex) {
      					logger.error("Couldn't invoke destroy method of attribute with name '" + attrName + "'", ex);
      				}
      			}
      		}
      	}
      

    记录总结

    1. web.xml中的listener节点具有先写先加载的特点,类似于java代码中的顺序执行

    2. Log4jConfigListener类加载必须在ContextLoaderListenr类之前

    3. ContextLoaderListener启动Spring并生成Spring根web服务上下文则是通过其父类ContextLoader来实现的,其销毁也只会销毁具有org.springwork前缀的属性

    4. ServletContext代表应用服务上下文,其可以读取<context-param>级别的参数,而ServletConfig/FilterConfig则会读取其相应servlet节点/filter节点下的<init-param>参数

    5. web.xml中listener、servlet、filter执行顺序为listener>filter>servlet,同类型的执行顺序为listener满足先写先加载,servlet、filter则由mapping节点的先后顺序加载

    下节预告

    Spring源码情操陶冶-ContextLoader

  • 相关阅读:
    RUST实践.md
    redis.md
    opencvrust.md
    aws rds can't connect to mysql server on 'xx'
    Foundation ActionScript 3.0 With Flash CS3 And Flex
    Foundation Flash Applications for Mobile Devices
    Flash Mobile Developing Android and iOS Applications
    Flash Game Development by Example
    Actionscript 3.0 迁移指南
    在SWT中非UI线程控制界面
  • 原文地址:https://www.cnblogs.com/question-sky/p/6683345.html
Copyright © 2011-2022 走看看