Spring源碼情操陶冶-ContextLoaderListener

前言:經過實例結合源碼的方式解讀,其中涉及到的文件來自於博主的Github畢設項目wxServer
Note: Springboot應用不在本文章討論範圍java

web.xml中啓用Spring

在通常的web應用程序,咱們假若用到Spring的話,須要在web.xml中配置如下的信息來使一些容器,例如TomcatJetty等來加載Springgit

<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類在應用啓動時加載其服務github

ContextLoaderListener的官方註釋

查看某個類的重要功能最好是觀察其的註釋,ContextLoaderLinstener官方註釋以下:web

//父級啓動類,可用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節點具備代碼邏輯上的先寫先加載的特色。spring

特別須要注意的是若是用戶須要用到Log4jConfigListener的話,則必須寫在ContextLoaderListener的前面app

ContextLoaderListener結構

public class ContextLoaderListener extends ContextLoader implements ServletContextListener{}

最應該關注的是ServletContextListenr接口,咱們應該知道實現此接口的類會在應用啓動的時候,自動的調用其接口方法contextInitialized(ServletContextEvent event);
關閉應用時候則會調用其另一個接口方法contextDestroyed(ServletContextEvent evet)用來關閉web上下文信息。spa

  • 初始化
    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代碼中的順序執行code

  2. Log4jConfigListener類加載必須在ContextLoaderListenr類以前xml

  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

相關文章
相關標籤/搜索