spring學習(六):spring容器內部工作機制

一、加載配置文件之後的各項操作流程

Spring的AbstractApplicationContextApplicationContext的抽象實現類,該類中的refresh()方法定義了spring容器在加載配置文件之後的各項操作流程,如下所示:

public void refresh() throws BeansException, IllegalStateException {
        synchronized(this.startupShutdownMonitor) {
            this.prepareRefresh();
            // 1.初始化beanFactory
            ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();
            this.prepareBeanFactory(beanFactory);

            try {
                this.postProcessBeanFactory(beanFactory);
                // 2.調用工廠後處理器
                this.invokeBeanFactoryPostProcessors(beanFactory);
                // 3.註冊 bean後處理器
                this.registerBeanPostProcessors(beanFactory);
                // 4.初始化消息源
                this.initMessageSource();
                // 5.初始化應用上下文事件廣播器
                this.initApplicationEventMulticaster();
                // 6.初始化其他特殊的bean,由具體子類實現
                this.onRefresh();
                // 7.註冊事件監聽器
                this.registerListeners();
                // 8.初始化所有單實例的bean,使用懶加載模式的除外
                this.finishBeanFactoryInitialization(beanFactory);
                // 9.完成刷新併發布容器刷新事件
                this.finishRefresh();
            } catch (BeansException var9) {
                this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt", var9);
                this.destroyBeans();
                this.cancelRefresh(var9);
                throw var9;
            } finally {
                this.resetCommonCaches();
            }

        }
    }
  1. 初始化BeanFactory:根據配置文件實例化BeanFactory,在obtainFreshBeanFactory()方法中,首先調用refreshBeanFactory()刷新,然後調用getBeanFactory()方法獲取beanFactory,這兩個方法都是由具體子類實現的。在這一步中,spring將配置文件裝入到容器的bean定義註冊表中(BeanDefinitionRegistry)中,但此時bean還未初始化
  2. 調用工廠後處理器:根據反射機制從BeanDefinitionRegistry中找出所有實現了BeanFactoryPostProcessor接口的bean,並調用其postProcessBeanFactory(ConfigurableListableBeanFactory var1)接口方法
  3. 註冊bean後處理器:根據反射機制從BeanDefinitionRegistry中找出所有實現了BeanPostProcessor接口的bean,並將他們註冊到容器bean後處理器的註冊表中
  4. 初始化消息源:初始化容器的國際化消息資源
  5. 初始化應用上下文事件廣播器
  6. 初始化其他特殊的bean:這是一個鉤子方法,子類可以藉助該方法實現一些特殊的操作。
  7. 註冊事件監聽器
  8. 初始化所有單實例的bean,使用懶加載模式的bean除外,初始化bean後,將他們放在spring容器的緩存池中
  9. 發佈上下文刷新事件,創建上下文刷新事件 ,事件廣播器負責將事件廣播到每個註冊的事件監聽器中

二、spring容器 從加載配置文件到創建一個完整的bean的流程如下所示:

  1. ResourceLoader從存儲介質中加載spring的配置信息,並使用Resource來表示這個配置文件資源
  2. BeanDefinitionReader讀取Resource所指向的配置資源,然後解析配置文件,配置文件的每個<bean>解析成一個BeanDefinition對象,並保存到BeanDefinitionRegistry中
  3. 容器掃描BeanDefinitionRegistry中的BeanDefinition,使用java反射機制自動識別出bean工廠後處理器(實現了實現了BeanFactoryPostProcessor接口的bean),然後調用這些工廠後處理器對BeanDefinition進行加工,主要完成一下兩項工作
    1. 對使用佔位符的<bean>元素標籤進行解析,得到最終的配置值,這意味着對一些半成品式的BeanDefinition對象進行加工並得到成品的BeanDefinition
    2. 對BeanDefinitionRegistry中的BeanDefinition進行掃描,通過java反射機制找出所有屬性編輯器的bean,(實現了java.beans.PropertyEditor接口的bean),並調用InstantiationStrategy着手進行bean實例化的工作
  4. 在實例化bean時,Spring容器使用BeanWrapper對Bean進行封裝。BeanWrapper提供了許多java反射操作 bean的方法,它將結合該 bean的BeanDefinition及容器中的屬性編輯器,完成bean屬性的注入操作
  5. 利用容器中註冊的Bean後處理器對已經完成屬性設置工作的Bean進行後續加工,直接裝配出一個準備就緒的bean
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章