Spring ApplicationContext(一)初始化過程

Spring 容器 ApplicationContext(一)初始化過程

Spring 系列目錄(http://www.javashuo.com/article/p-kqecupyl-bm.html)html

1. Spring ApplicationContext(一)初始化過程
2. Spring ApplicationContext(二)環境準備
3. Spring ApplicationContext(三)BeanFactory 初始化
4. Spring ApplicationContext(四)BeanFactory 功能擴展
5. Spring ApplicationContext(五)BeanFactoryPostProcessor
6. Spring ApplicationContext(六)BeanPostProcessor
7. Spring ApplicationContext(七)Message 源
8. Spring ApplicationContext(八)事件監聽機制
9. Spring ApplicationContext(九)初始化非延遲的 bean
10. Spring ApplicationContext(十)finishRefreshjava

咱們以 ClassPathXmlApplicationContext 做爲切入點研究 ApplicationContext 的初始化過程。程序員

public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
    this(new String[] {configLocation}, true, null);
}

public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, ApplicationContext parent)
            throws BeansException {
    // 1. 設置父容器
    super(parent);
    // 2. 設置配置文件路徑,調用 getEnvironment().resolveRequiredPlaceholders(path) 方法解析路徑中的佔位符
    setConfigLocations(configLocations);
    // 3. 刷新容器,即從新初始化 bean 工廠
    if (refresh) {
        refresh();
    }
}

1、refresh

下面咱們重點關注 refresh() 方法都做了那些事。spring

public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        // 1. 刷新上下文環境
        prepareRefresh();

        // 2. 初始化 beanFactory,對配置文件進行解讀
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        // 3. 對 beanFactory 進行功能擴展
        prepareBeanFactory(beanFactory);

        try {
            // 4. 專門留給子類做擴展用,這是一個空的方法
            postProcessBeanFactory(beanFactory);

            // 5. 註冊並執行 BeanFactoryPostProcessor 後置處理器
            invokeBeanFactoryPostProcessors(beanFactory);

            // 6. 註冊 BeanPostProcessor 後置處理器,在 getBean() 建立 bean 時調用
            registerBeanPostProcessors(beanFactory);

            // 7. 初始化 Message 源,即不一樣語言消息體,國際化處理
            initMessageSource();

            // 8. 註冊多播器,事件監聽器的管理者
            initApplicationEventMulticaster();

            // 9. 專門留給子類初始化其它 bean 用,這是一個空的方法
            onRefresh();

            // 10. 註冊監聽器
            registerListeners();

            // 11. 初始化剩餘的 bean (部分在 invokeBeanFactoryPostProcessors 已經初始化)
            finishBeanFactoryInitialization(beanFactory);

            // 12. 完成刷新,通知生命週期處理器 LifecycleProcessor 刷新過程,同時發佈 ContextRefreshedEvent 通知別人
            finishRefresh();
        } catch (BeansException ex) {
            destroyBeans();
            cancelRefresh(ex);
            throw ex;
        } finally {
            resetCommonCaches();
        }
    }
}

下面歸納一下 ClassPathXmlApplicationContext 初始化的步驟,並從中解釋一下它爲咱們提供的功能。架構

(1) 初始化前的準備工做,例如對系統屬性或者環境變量進行準備及驗證。app

在某種狀況下項目的使用須要讀取某些系統變量,而這個變量的設置極可能會影響着系統的正確性,那麼 ClassPathXmlApplicationContext 爲咱們提供的這個準備函數就顯得很是必要,它能夠在 Spring 啓動的時候提早對必須的變量進行存在性驗證函數

(2) 初始化 BeanFactory,並進行 XML 文件讀取。post

以前有提到 ClassPathXmlApplicationContext 包含着 BeanFactory 所提供的一切特徵,那麼在這一步驟中將會複用 BeanFactory 中的配置文件讀取解析及其餘功能,這一步以後,ClassPathXmlApplicationContext 實際上就已經包含了 BeanFactory 所提提供的功能,也就是能夠進行 Bean 的提取等基礎操做了。ui

(3) 對 BeanFactory 進行各類功能填充。this

@Qualifier 與 @Autowired 應該是你們很是熟悉的註解,那麼這兩個註解正是在這一步驟中增長的支持。

(4) 子類覆蓋方法作額外的處理。

Spring 之因此強大,爲世人所推崇,除了它功能上爲你們提供了便例外,還有一方面是它的完美架構,開放式的架構讓使用它的程序員很容易根據業務須要擴展已經存在的功能。這種開放式的設計在 Spring 中隨處可見,例如在本例中就提供了一個空的函數實現 postProcessBeanFactory 來方便程序員在業務上作進一步擴展。

(5) 激活各類 BeanFactory 處理器。

(6) 註冊攔截 bean 建立的 bean 處理器,這裏只是註冊,真正的調用是在 getbean 時候。

(7) 爲上下文初始化 Message 源,即對不一樣語言的消息體進行國際化處理。

(8) 初始化應用消息廣播器,並放人 "applicationeventMulticaster" bean中。

(9) 留給子類來初始化其餘的 bean。

(10) 在全部註冊的 bean 中查找 listener bean,註冊到消息廣播器中。

(11) 初始化剩下的單實例(非惰性的)。

(12) 完成刷新過程,通知生命週期處理器 lifecycleProcessor 刷新過程,同時發出 ContextRefreshEvent 通知別人。


天天用心記錄一點點。內容也許不重要,但習慣很重要!

相關文章
相關標籤/搜索