前言:經過實例結合源碼的方式解讀,其中涉及到的文件來自於博主的Github畢設項目wxServer
Note: Springboot應用不在本文章討論範圍java
在通常的web應用程序,咱們假若用到Spring的話,須要在web.xml中配置如下的信息來使一些容器,例如Tomcat
、Jetty
等來加載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
查看某個類的重要功能最好是觀察其的註釋,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
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); } } } }
web.xml中的listener節點具備先寫先加載的特色,相似於java代碼中的順序執行code
Log4jConfigListener類加載必須在ContextLoaderListenr類以前xml
ContextLoaderListener啓動Spring並生成Spring根web服務上下文則是經過其父類ContextLoader來實現的,其銷燬也只會銷燬具備
org.springwork
前綴的屬性接口ServletContext表明應用服務上下文,其能夠讀取
<context-param>
級別的參數,而ServletConfig/FilterConfig則會讀取其相應servlet節點/filter節點
下的<init-param>
參數web.xml中listener、servlet、filter執行順序爲listener>filter>servlet,同類型的執行順序爲listener知足先寫先加載,servlet、filter則由
mapping
節點的前後順序加載
Spring源碼情操陶冶-ContextLoader