springmvc web.xml配置之 -- SpringMVC IOC容器初始化


SpringMVC IOC容器初始化

首先強調一下SpringMVC IOC容器初始化有些特別,在SpringMVC中除了生成一個全局的spring Ioc容器外,還會為DispatcherServlet生成一個容器,具體的下一篇有講述。

我們知道spring中單純使用main函數就可以生成一個容器,如下:

public class MainTest {
    public static void main(String[] args){
        ApplicationContext appContext = new ClassPathXmlApplicationContext("cjj/models/beans.xml");
        Person p = (Person)appContext.getBean("person");
    }
}

以前專門寫過一篇spring Ioc容器初始化過程的文章 《Spring IoC容器初始化過程學習》,感興趣可以看看。該文中注意介紹了Spring IOC容器初始化過程一般需要三個步驟,

  1. Resource定位(Bean的定義文件定位)
  2. 將Resource定位好的資源載入到BeanDefinition
  3. 將BeanDefiniton注冊到容器中

那篇文章中強調的是bean的加載過程,也是核心過程,這個過程可查閱源代碼中的obtainFreshBeanFactory過程 ,該過程中會執行refreshBeanFactory會創建一個beanFactory實例(默認類型為DefaultListableBeanFactory),以及loadBeanDefinitions(defaultListableBeanFactory)。

但是spring容器初始化的過程遠遠 不止文中介紹的那么多,還有一個重要的refresh方法需要進行補充。那么本文可以結合web.xml配置加載來簡單的闡述refresh方法執行力那些邏輯。

如果你不太了解應用啟動時容器初始化web.xml的作用,建議先看一下之前的文章《springmvc web.xml配置之ContextLoaderListener》,該文中介紹了Spring中ContextLoaderListener的作用,知道ContextLoaderListener首先會常見一個XmlWebApplicationContext類型的IOC容器,然后讀取配置文件信息進行初始化,如果沒有寫,那就默認為/WEB-INF/applicationContext.xml,可以查閱源碼:

public class XmlWebApplicationContext extends AbstractRefreshableWebApplicationContext {
    public static final String DEFAULT_CONFIG_LOCATION = "/WEB-INF/applicationContext.xml";
    public static final String DEFAULT_CONFIG_LOCATION_PREFIX = "/WEB-INF/";
    public static final String DEFAULT_CONFIG_LOCATION_SUFFIX = ".xml";
    ...(略)

一般會在web.xml配置,如下:

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath*:spring/applicationcontext-*.xml</param-value>
</context-param>

例如像上面這么配置的話,XmlWebApplicationContext容器就會將applicationcontext-*.xml配置文件中的信息讀取到,然后調用refresh()方法,由於XmlWebApplicationContext implements於ConfigurableApplicationContext,也就是實現了ConfigurableApplicationContext.refresh()方法,該方法會將這些配置信息加載到IOC容器中。

具體的,XmlWebApplicationContext繼承於AbstractApplicationContext,它實現了ConfigurableApplicationContext接口中的refresh方法:

public void refresh() throws BeansException, IllegalStateException {
    Object var1 = this.startupShutdownMonitor;
    synchronized(this.startupShutdownMonitor) {
        this.prepareRefresh();
        ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
        this.prepareBeanFactory(beanFactory);

        try {
            this.postProcessBeanFactory(beanFactory);
            this.invokeBeanFactoryPostProcessors(beanFactory);
            this.registerBeanPostProcessors(beanFactory);
            this.initMessageSource();
            this.initApplicationEventMulticaster();
            this.onRefresh();
            this.registerListeners();
            this.finishBeanFactoryInitialization(beanFactory);
            this.finishRefresh();
        } catch (BeansException var9) {
            if(this.logger.isWarnEnabled()) {
                this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt: " + var9);
            }
    
            this.destroyBeans();
            this.cancelRefresh(var9);
            throw var9;
        } finally {
            this.resetCommonCaches();
        }

    }
}

  

  • prepareRefresh()

准備工作,一是設置spring啟動事件,開啟活躍狀態;二是初始化屬性源信息;三是驗證必要屬性。

  • obtainFreshBeanFactory()

創建beanFactory(過程是根據xml為每個bean生成BeanDefinition並注冊到生成的beanFactory)

  • prepareBeanFactory(beanFactory)

注冊bean等。

  • postProcessBeanFactory(beanFactory)

繼上一步beanfactory設置之后進行后續操作

  • invokeBeanFactoryPostProcessors(beanFactory)

  • registerBeanPostProcessors(beanFactory)

例化和注冊beanFactory中擴展了BeanPostProcessor的bean

  • initMessageSource()

初始化國際化屬性。

  • initApplicationEventMulticaster

初始化事件廣播器,用於發布事件。

  • onRefresh()

設置樣式工具ThemeSource

  • registerListeners()
  • finishBeanFactoryInitialization(beanFactory)
  • finishRefresh()

更多具體細節可以參考: https://www.cnblogs.com/lkdirk/p/7145941.html 。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM