SpringIOC容器創建過程


在測試時,經常使用這種方式來創建spring容器

//創建基於注解的springIOC容器
ApplicationContext applicationContext = new AnnotationConfigApplicationContext(AopBeanConfig.class);
//創建基於配置文件的springIOC容器
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("/spring-beans.xml");

無論哪種方式,最終都會調用AbstractApplicationContext的一個重要方法——refresh(),首先來看這個方法的spring源碼

    @Override
    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // 1. Prepare this context for refreshing.
            prepareRefresh();

            // 2. Tell the subclass to refresh the internal bean factory. 
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            // 3. Prepare the bean factory for use in this context. 
            prepareBeanFactory(beanFactory);

            try {
                // 4. Allows post-processing of the bean factory in context subclasses.
                postProcessBeanFactory(beanFactory);

                // 5. Invoke factory processors registered as beans in the context.
                invokeBeanFactoryPostProcessors(beanFactory);

                // 6. Register bean processors that intercept bean creation.
                registerBeanPostProcessors(beanFactory);

                // 7. Initialize message source for this context.
                initMessageSource();

                // 8. Initialize event multicaster for this context.
                initApplicationEventMulticaster();

                // 9. Initialize other special beans in specific context subclasses.
                onRefresh();

                // 10. Check for listener beans and register them.
                registerListeners();

                // 11. Instantiate all remaining (non-lazy-init) singletons.
                finishBeanFactoryInitialization(beanFactory);

                // 12. Last step: publish corresponding event.
                finishRefresh();
            }

            catch (BeansException ex) {
                if (logger.isWarnEnabled()) {
                    logger.warn("Exception encountered during context initialization - " +
                            "cancelling refresh attempt: " + ex);
                }

                // Destroy already created singletons to avoid dangling resources.
                destroyBeans();

                // Reset 'active' flag.
                cancelRefresh(ex);

                // Propagate exception to caller.
                throw ex;
            }

            finally {
                // Reset common introspection caches in Spring's core, since we
                // might not ever need metadata for singleton beans anymore...
                resetCommonCaches();
            }
        }
    }

 

重點步驟簡析 

1. prepareRefresh  准備刷新容器

  (1) initPropertySources()  自定義屬性設置,空方法,留給子類繼承

  (2) getEnvironment.validateRequiredProperties  首先獲取環境配置,然后校驗必需屬性

  (3) this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners); 

           初始化事件監聽器

  (4) this.earlyApplicationEvents = new LinkedHashSet<>();  初始化早期事件

2. obtainFreshBeanFactory  獲取組件工廠

  (1) refreshBeanFactory  新建一個組件工廠,類型為DefaultListableBeanFactory,

          然后對這個組件工廠設置了一個序列化ID

  (2) getBeanFactory 返回剛剛創建的組件工廠

3. prepareBeanFactory  對組件工廠做各種預處理設置

  (1) 在組件工廠中設置類加載器、屬性解析器等

  (2) 在組件工廠中添加部分組件后置處理器,例如ApplicationContextAwareProcessor、ApplicationListenerDetector

  (3) 在組件工廠中設置忽略自動注入的接口

  (4) 設置自動裝配規則

  (5) 在組件工廠中注冊一些組件,例如環境配置ConfigurableEnvironment

4. postProcessBeanFactory  組件工廠的后置處理工作

5. invokeBeanFactoryPostProcessors 執行組件工廠后置處理器

  這一步是在組件工廠的標准初始化(1-4)之后進行的,主要是執行BeanFactoryPostProcessor及其子接口的

  BeanFactoryPostProcessor的子接口主要是指BeanDefinitionRegistryPostProcessor,可以向容器中注冊新的組件,這個接口的特點是有兩個方法,一個是自身的postProcessBeanDefinitionRegistry,另一個繼承自BeanFactoryPostProcessor的postProcessBeanFactory,從源碼可以看出,spring會先執行BeanDefinitionRegistryPostProcessor類型的組件的自身方法,然后執行其繼承方法,最后才調用非BeanDefinitionRegistryPostProcessor的BeanFactoryPostProcessor的后置處理方法

  (1) 從容器器中獲取BeanDefinitionRegistryPostProcessor類型的組件

  (2) 將BeanDefinitionRegistryPostProcessor類型的組件按照順序分類並排序,即是否實現了PriorityOrdered、Ordered接口

    (3) 依次執行實現了PriorityOrdered接口的、實現了Ordered接口的、沒有實現任何順序接口的組件的postProcessBeanDefinitionRegistry方法

  (4) 執行所有BeanDefinitionRegistryPostProcessor組件的postProcessBeanFactory方法

  (5) 從容器中獲取其他的BeanFactoryPostProcessor類型的組件,即不是BeanDefinitionRegistryPostProcessor類型的

  (6) 剩下的步驟跟上面類似,就是先按照實現的順序接口分類,在每個類別下排序,然后依次執行它們的postProcessBeanFactory方法

6. registerBeanPostProcessors 注冊組件后置處理器,這種處理器用於攔截bean的創建過程

beanPostProcessor有很多子接口,每種子接口的執行時機各有不同

  |-DestructionAwareBeanPostProcessor

  |-InstantiationAwareBeanPostProcessor  

  |-MergedBeanDefinitionPostProcessor

  |-SmartInstantiationAwareBeanPostProcessor

  (1) 獲取所有的beanPostProcessor的組件名

      (2) 將所有的組件按優先順序分為三類:

     |-實現了PriorityOrdered接口的列表priorityOrderedPostProcessors

     |-實現了Ordered接口的列表orderedPostProcessors

       |-沒有實現任何順序接口的列表nonOrderedPostProcessors

      還有一種特殊情況,凡是MergedBeanDefinitionPostProcessor類型的,都放在internalPostProcessors中

    (3) 注冊priorityOrderedPostProcessors

  (4) 注冊orderedPostProcessors

  (5) 注冊nonOrderedPostProcessors

  (6) 注冊internalPostProcessors

  (7) 注冊ApplicationListenerDetector,它的作用是在組件初始化之后判斷其是否為

           ApplicationListner類型,如果是,則將其添加進容器的監聽器集合

7. initMessageSource 初始化消息源組件,用於消息綁定、消息解析等功能,並且提供國際化解決方案

  (1) 獲取beanFactory

  (2) 判斷beanFactory中是否包含id為messageSource的組件

  (3) 如果已存在,則賦值給容器的messageSource屬性,這種情況是我們自己在容器中注冊了這個組件

  (4) 如果不存在,則新建一個DelegatingMessageSource,並賦值給容器的messageSource屬性,

           然后在beanFactory中注冊這個新組件,並設置其id為messageSource

8. initApplicationEventMulticaster 初始化事件廣播器

  (1) 獲取beanFactory

  (2) 判斷beanFactory中是否存在id為applicationEventMulticaster的組件

  (3) 如果已存在,則賦值給容器的applicationEventMulticaster屬性,這種情況是我們自己在容器中注冊了這個組件

  (4) 如果不存在,則新建一個SimpleApplicationEventMulticaster,並賦值給容器的

           applicationEventMulticaster屬性,然后在beanFactory中注冊這個新組件,

           並設置其id為applicationEventMulticaster

9. onRefresh 沒有任何操作,留給子類繼承的,我們可以自定義子容器,在重寫方法中做一些我們想要的操作

10. registerListeners 注冊事件監聽器

  (1) 獲取容器的屬性applicationListeners,這是一個事件監聽器的集合,將集合中的每個元素都添加進事件廣播器

  (2) 從容器中獲取所有ApplicationListener類型的組件,將這些組件添加進事件廣播器

  (3) 發布早期事件,即容器的earlyApplicationEvents屬性(參考第1(4)步),然后清空早期事件

11. finishBeanFactoryInitialization 完成剩下的單實例bean的初始化

  (1) 進入DefaultListableBeanFactory.preInstantiateSingletons方法,獲取容器中所有的組件id列表

  (2) 遍歷組件id列表,對每個組件,獲取其組件定義信息,即RootBeanDefinition

  (3) 從組件定義信息中篩選掉抽象類、非單實例、懶加載的,這些bean在創建容器時並不初始化,

           另外還有工廠組件,即實現了FactoryBean接口的,需要另外一套邏輯進行初始化

  (4) 從緩存中獲取單實例bean,即DefaultSingletonBeanRegistry類的singletonObjects屬性,所有被創建過的

           單實例bean都會被緩存在這個映射中;如果緩存中存在,說明這個組件之前被創建過,直接返回

  (5) 如果緩存中不存在,則開始新建

     ① 將組件標記為已創建,即將其id存入AbstractBeanFactory的alreadyCreated屬性中

     ② 獲取組件的定義信息,即RootBeanDefinition

     ③ 從定義信息中獲取該組件依賴的組件,如果存在,則重新從第11(4)步開始執行,創建這些依賴的組件

     ④ 創建完依賴組件(如果存在)之后,以下開始正式新建目標組件

     ⑤ 給組件后置處理器一個機會用代理對象代替目標對象,即執行InstantiationAwareBeanPostProcessor

               類型的組件后置處理器的postProcessBeforeInstantiation、postProcessAfterInitialization方法

       ⑥ Allow post-processors to modify the merged bean definition,即執行

               MergedBeanDefinitionPostProcessor類型組件后置處理器的postProcessMergedBeanDefinition方法

     ⑦ 執行AbstractAutowireCapableBeanFactory.populateBean方法,即屬性賦值

               在屬性賦值之前,首先拿到InstantiationAwareBeanPostProcessor類型的組件后置處理器,

       並執行postProcessAfterInstantiation、postProcessProperties、postProcessPropertyValues方法;

       然后才執行該類的applyPropertyValues方法,利用反射調用組件的setter方法進行屬性賦值

     ⑧ 執行以下三種aware接口的方法:BeanNameAware、BeanClassLoaderAware、BeanFactoryAware

     ⑨ 執行組件后置處理器的初始化前方法,即BeanPostProcessor.postProcessBeforeInitialization

           ⑩ 執行組件的初始化方法,即InitializingBean.afterPropertiesSet,以及在容器中自定義的initMethod

       ⑪ 執行組件后置處理器的初始化后方法,即BeanPostProcessor.postProcessAfterInitialization

       ⑫ 如果需要,注冊組件的銷毀方法,例如DisposableBean.destroy,以及在容器中自定義的destroyMethod

               這里只是注冊,並不調用

  (6) 通過第11(5)步,單實例bean已經創建並初始化完成,接着,會調用AbstractBeanFactory的父類方法——

     DefaultSingletonBeanRegistry.getSingleton方法,將新建的bean存入singletonObjects屬性中,即緩存

  (7) 回到DefaultListableBeanFactory.preInstantiateSingletons方法(見第11(1)步)

       如果新建的bean實現了SmartInitializingSingleton接口,則執行afterSingletonsInstantiated回調方法

12. finishRefresh 完成容器刷新

  (1) 初始化生命周期處理器(LifecycleProcessor),先從BeanFactory中按類型獲取,

          如果沒有就新建一個DefaultLifecycleProcessor,並注冊進BeanFactory

  (2) 獲取上一步注冊的生命周期處理器,回調其onRefresh方法

  (3) 發布容器刷新事件,即ContextRefreshedEvent


免責聲明!

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



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