Spring學習筆記——ApplicationContext初始化


Spring上下文ApplicationContext接口,初始化實現在AbstractApplicationContext中

 

初始化流程:

 

public void refresh() throws BeansException, IllegalStateException {

   synchronized (this.startupShutdownMonitor) {  //線程安全

      // Prepare this context for refreshing.

      prepareRefresh();//初始化標記值和Environment

 

      // Tell the subclass to refresh the internal bean factory.

      ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); //初始化BeanFactory並掃描BeanDefinitions

 

      // Prepare the bean factory for use in this context.

      prepareBeanFactory(beanFactory);//BeanFactory初始化屬性值,並且添加各種回調處理器,如ApplicationAware


      try {

         // Allows post-processing of the bean factory in context subclasses.

         postProcessBeanFactory(beanFactory);//初始化BeanFactoryApplicationContext自定義操作

 

         // Invoke factory processors registered as beans in the context.

         invokeBeanFactoryPostProcessors(beanFactory);//調用BeanFactoryPostProcessor,先調用BeanDefinitionRegistryPostProcessor,按PriorityOrdered->Ordered->None順序調用,而后調用BeanFactoryPostProcessor,順序與前面相同

 

         // Register bean processors that intercept bean creation.

         registerBeanPostProcessors(beanFactory);//注冊BeanPostProcessor,當BeanFactory.createBean被調用時,會依次調用BeanPostProcessor

 

         // Initialize message source for this context.

         initMessageSource();//若存在自定義MessageSource則用,否則取空

 

         // Initialize event multicaster for this context.

         initApplicationEventMulticaster();//初始化應用事件多點推送


         // Initialize other special beans in specific context subclasses.
         
onRefresh();//
自定義刷新上下文操作

         // Check for listener beans and register them.

         registerListeners();//注冊應用事件


         // Instantiate all remaining (non-lazy-init) singletons.
         
finishBeanFactoryInitialization(beanFactory);//
初始化非lazy-init單例對象

         // Last step: publish corresponding event.

         finishRefresh();//發布刷新完成事件

      }

   }

        

}

 

 

具體邏輯:

 

1.prepareRefresh方法,主要作用:初始化各標記值,初始化Environment,從配置的propertySources讀取配置

 

2.obtainFreshBeanFactory方法:獲取新的BeanFactory,即初始化BeanFactory,refreshBeanFactory方法由具體類實現,在AbstractRefeshableApplicationContext中,將會掃描BeanDefinition

 

 

3.prepareBeanFactory方法,向BeanFactory中添加初始化必須的屬性及Bean,如自動裝配處理器、資源自動注入處理器、各種默認回調接口處理

 

4.自定義BeanFactory初始化后操作,添加BeanPostProcessor處理器ServletContextAwareProcessor

 

5.調用之前注冊的BeanFactoryPostProcessor,實質上調用PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessor方法

          (1)getBeanFactoryPostProcessor()方法獲取默認上下文BeanFactoryProcessor列表

          (2)invokeBeanFactoryPostProcessor方法調用,先調用所有BeanDefinitionRegistryPostProcessor對BeanDefinition操作,而后對所有由ApplicationContext.addPostProcessor方法添加的BeanFactoryPostProcessor執行postBeanFactory操作

               a)BeanFactoryPostProcessor分類成常規和Registry

     b)從BeanDefinitions中獲取BeanDefinitionRegistryPostProcessor類型,如果實現PriorityOrdered接口表明屬於優先級排序的PostProcessor,排序后加入到registryPostProcessors中,優先調用

 

              

                      

 

               c)調用實現自Ordered接口的BeanDefinitionRegistryPostProcessor實現

 

     d) 調用所有BeanDefinitionRegistryPostProcessor實現,及BeanFactoryPostProcessor方法

     e)獲取所有實現BeanFactoryPostProcessor接口的BeanDefinition,與以上邏輯相同,先處理實現PriorityOrdered->Ordered->none順序處理

    

6.注冊BeanPostProcessor至BeanFactory中,當BeanFactory.createBean方法被調用時,會先按順序調用所有BeanPostProcessor

     a)掃描BeanDefinition中所有BeanPostProcessor接口實現類,先添加BeanPostProcessorChecker,用於打印日志

     

     b)按照PriorityOrdered>Ordered>NonOrder順序對BeanPostProcessor進行分類

     

     c)排序后將其加入到BeanFactory中,最后添加ApplicationListenerDetecter用於發現ApplicationListener,將其添加到上下文ApplicationContext中

7.初始化MessageSource

     a)若BeanDefinitions中包含MessageSource,則將其注入到ApplicationContext中

     

     b)若無自定義MessageSource,則默認采用空MessageSource

          

8.初始化應用事件多點傳送,若包含自定義Bean則取自定義Bean,否則取SimpleApplicationEventMulticaster,用於向應用監聽器發送事件

9.刷新操作,由子類自定義實現

10.注冊Listener到ApplicationEventMutilcaster

     

11.初始化非lazy-init的單例對象

    

12.發布完成刷新事件

     

 


免責聲明!

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



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