spring學習:六(第一部分)Spring容器高級主題

Spring容器技術內幕

1.內部工作機制

Spring的AbstractApplicationContext是ApplicationContext的抽象實現類,該抽象類的reflesh方法定義了Spring容器在加載配置文件後的各項處理過程,這些處理過程清晰地刻畫了Spring容器啓動時所執行的各項操作,方法如下所示:

public void refresh() throws BeansException, IllegalStateException {
        synchronized(this.startupShutdownMonitor) {
            this.prepareRefresh();
            // 1.初始化bean工廠
            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,使用懶加載模式的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()方法中,首先調用refleshBeanFactory方法刷新BeanFactory,然後調用getBeanFactory()方法獲取BeanFactory,這兩個方法都是由具體子類實現的 。在這一步,Spring將配置文件的信息裝入容器的Bean定義註冊表(BeanDefinitionRegistry)中,但此時Bean還未初始化
  2. 調用工廠後處理器:根據反射機制從BeanDefinitionRegistry中找出所有實現了BeanFactoryPostProcessor接口的bean,並調用其postProcessBeanFactory方法接口方法。
  3. 註冊bean後處理器:根據反射機制從BeanDefinitionRegistry中找出所有實現類BeanPostProcessor接口的bean,並將它們註冊到容器Bean後處理器的註冊表中
  4. 初始化消息源:初始化容器的國際化消息資源
  5. 初始化應用上下文事件廣播器
  6. 初始化其他特殊的bean:這是一個鉤子方法,子類可以藉助這個方法執行一些特殊的操作,如AbstractRefreshableWebApplicationContext就使用執行初始化ThemeSource的 操作
  7. 註冊事件監聽器
  8. 初始化所有單實例的bean,使用懶加載模式的bean除外:初始化bean後,將他們放在Spring的容器緩存池中
  9. 發佈上下文刷新事件:創建上下文刷新事件,事件廣播器負責將這些事件廣播到每個註冊的事件監聽器中

2.Spring從加載配置文件到創建一個完整的bean的作業流程

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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章