Spring mvc ContextLoaderListener 原理解析

對於熟悉Spring MVC功能,首先應從web.xml 開始,在web.xml 文件中咱們須要配置一個監聽器 ContextLoaderListener,以下。web

<!-- 加載spring上下文信息,最主要的功能是解析applicationContext.xml -->
<listener>  
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  
</listener>  

<!-- 配置applicationContext.xml的位置路徑,讓ContextLoaderListener進行加載該配置文件,並解析 -->
<context-param>
    <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml
    </param-value>
</context-param>

ContextLoaderListener有什麼用?提供什麼功能呢?咱們下面經過源碼分析下。spring

ContextLoaderListener 源碼分析

public class ContextLoaderListener extends ContextLoader implements ServletContextListener {

    public ContextLoaderListener() {
    }

    public ContextLoaderListener(WebApplicationContext context) {
        super(context);
    }

    //web 容器啓動時執行
    @Override
    public void contextInitialized(ServletContextEvent event) {
        //初始化WebApplicationContext對象
        initWebApplicationContext(event.getServletContext());
    }
    //web容器銷燬時執行
    @Override
    public void contextDestroyed(ServletContextEvent event) {
        closeWebApplicationContext(event.getServletContext());
        ContextCleanupListener.cleanupAttributes(event.getServletContext());
    }
}

ContextLoaderListener 實現了ServletContextListener 接口。
ServletContextListener 接口咱們知道是web容器建立的時候開始執行contextInitialized() 方法,web容器銷燬時執行contextDestroyed() 方法。那咱們就從contextInitialized() 方法開始分析。app

contextInitialized() 方法

public void contextInitialized(ServletContextEvent event) {
    //初始化WebApplicationContext對象
    initWebApplicationContext(event.getServletContext());
}

initWebApplicationContext() 方法

  1. 首先判斷servletContext中是否存在WebApplicationContext實例,若是存在說明ServletContextListener在web.xml中屢次聲明,並拋出異常。
  2. 調用 createWebApplicationContext() 方法建立WebApplicationContext實例
  3. 調用configureAndRefreshWebApplicationContext() 方法經過WebApplicationContext進行解析web.xml中配置的applicationContext.xml。
  4. 把WebApplicationContext實例添加到ServletContext中

createWebApplicationContext()

  1. 調用 determineContextClass() 方法獲取WebApplicationContext的Class實例
  2. 經過反射建立WebApplicationContext對象,並返回。

determineContextClass()

  1. 首先判斷 servletContext中是否存在contextClass,若是有則直接返回該Class 實例(默認是沒有配置該值的)
  2. 從defaultStrategies中經過WebApplicationContext全類名(包名和類名)獲取要實現WebApplicationContext接口的類。

defaultStrategies

從當前類的路徑下查找 ContextLoader.properties 並加載文件中的鍵值存儲到 defaultStrategies中。ide

ContextLoader.properties

# Default WebApplicationContext implementation class for ContextLoader.
# Used as fallback when no explicit context implementation has been specified as context-param.
# Not meant to be customized by application developers.

org.springframework.web.context.WebApplicationContext=org.springframework.web.context.support.XmlWebApplicationContext

經過WebApplicationContext全類名獲取它的實現類是XmlWebApplicationContext。源碼分析

configureAndRefreshWebApplicationContext()

  1. 獲取web.xml中配置的applicationContext.xml路徑
  2. 調用refresh()進行加載xml,解析bean。

總結

經過代碼分析ContextLoaderListener的做用就是啓動Web容器的時候,初始化WebApplicationContext實例,並存放到ServletContext中。spa

ContextLoaderListener實現了ServletContextListener接口,在Web容器啓動的時會默認執行它的contextInitialized() 方法,而後獲取WebApplicationContext的實現類 XmlWebApplicationContext,並實例化後存放到ServletContext中,經過XmlWebApplicationContext類進行加載、解析applicationContext.xml 配置文件。ServletContext在整個Web容器範圍內都有效,均可以獲取獲得。3d

XmlWebApplicationContext類的做用

經過代碼能夠大概瞭解到就是讀取web.xml中配置的applicationContext.xml ,而後加載解析Bean信息。code

相關文章
相關標籤/搜索