Spring 啟動 Bean加載流程


  1. spring 啟動類 SpringApplication.run(PpApplication.class,args)
  2. AnnotationConfigEmbeddedWebApplicationContext context = createAndRefreshContext(listeners, applicationArguments);context里面默認帶有一個beanFactory,而這個beanFactory的類型為DefaultListableBeanFactory
  3. refresh
    1. 該方法中,我們這次需要注意的地方有兩個:
      1、invokeBeanFactoryPostProcessors(beanFactory);
      2、finishBeanFactoryInitialization(beanFactory);
      兩處傳入的beanFactory為上面的context中的DefaultListableBeanFactory。

    2.  1 @Override
       2 public void refresh() throws BeansException, IllegalStateException {
       3   synchronized (this.startupShutdownMonitor) {
       4     // 刷新前准備工作,包括設置啟動時間,是否激活標識位,初始化屬性源(property source)配置
       5     prepareRefresh();
       6 
       7     // 創建beanFactory(過程是根據xml為每個bean生成BeanDefinition並注冊到生成的beanFactory
       8     ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
       9 
      10     //准備創建好的beanFactory(給beanFactory設置ClassLoader,設置SpEL表達式解析器,設置類型轉化器【能將xml String類型轉成相應對象】,
      11     //增加內置ApplicationContextAwareProcessor對象,忽略各種Aware對象,注冊各種內置的對賬對象【BeanFactory,ApplicationContext】等,
      12     //注冊AOP相關的一些東西,注冊環境相關的一些bean
      13     prepareBeanFactory(beanFactory);
      14 
      15     try {
      16       // 模板方法,為容器某些子類擴展功能所用(工廠后處理器)這里可以參考BeanFactoryPostProcessor接口的postProcessBeanFactory方法
      17       postProcessBeanFactory(beanFactory);
      18 
      19       // 調用所有BeanFactoryPostProcessor注冊為Bean
      20       invokeBeanFactoryPostProcessors(beanFactory);
      21 
      22       // 注冊所有實現了BeanPostProcessor接口的Bean
      23       registerBeanPostProcessors(beanFactory);
      24 
      25       // 初始化MessageSource,和國際化相關
      26       initMessageSource();
      27 
      28       // 初始化容器事件傳播器
      29       initApplicationEventMulticaster();
      30 
      31       // 調用容器子類某些特殊Bean的初始化,模板方法
      32       onRefresh();
      33 
      34       // 為事件傳播器注冊監聽器
      35       registerListeners();
      36 
      37       // 初始化所有剩余的bean(普通bean)
      38       finishBeanFactoryInitialization(beanFactory);
      39 
      40       // 初始化容器的生命周期事件處理器,並發布容器的生命周期事件
      41       finishRefresh();
      42     }
      43     catch (BeansException ex) {
      44       if (logger.isWarnEnabled()) {
      45         logger.warn("Exception encountered during context initialization - " +
      46             "cancelling refresh attempt: " + ex);
      47       }
      48       // 銷毀已創建的bean
      49       destroyBeans();
      50       // 重置`active`標志
      51       cancelRefresh(ex);
      52       throw ex;
      53     }
      54     finally {
      55               //重置一些緩存
      56       resetCommonCaches();
      57     }
      58   }
      59 }
      refresh()
    3. 在這里我想說一下,這個refresh()方法其實是一個模板方法, 很多方法都讓不同的實現類去實現,但該類本身也實現了其中一些方法,並且這些已經實現的方法是不允許子類重寫的,比如:prepareRefresh()方法。
    4.  1 protected void prepareRefresh() {
       2   this.startupDate = System.currentTimeMillis();//設置容器啟動時間
       3   this.closed.set(false);//容器關閉標志,是否關閉?
       4   this.active.set(true);//容器激活標志,是否激活?
       5   
       6   if (logger.isInfoEnabled()) {//運行到這里,控制台就會打印當前容器的信息
       7     logger.info("Refreshing " + this);
       8   }
       9 
      10   // 空方法,由子類覆蓋實現,初始化容器上下文中的property文件
      11   initPropertySources();
      12 
      13   //驗證標記為必需的所有屬性均可解析,請參閱ConfigurablePropertyResolver#setRequiredProperties
      14   getEnvironment().validateRequiredProperties();
      15 
      16   //允許收集早期的ApplicationEvents,一旦多播器可用,即可發布...
      17   this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();
      18 }
      prepareRefresh()
  4. invokeBeanFactoryPostProcessors.invokeBeanDefinitionRegistryPostProcessors 注冊bean
  5. postProcessor.postProcesBeanDefinitionRegistry(registry),內部方法,解析日常注解
  6. processConfigurationClass.componentScanParser  將帶有@bean注解的類進行registry
  7. componentScanParser.parse,結尾的scanner.doScan,掃描basepackages,並將掃描到的bean生成一個個BeanDefinitionHolder;並執行后續的registerBeanDefinition,將其添加到beanFactory
  8. registry.registerBeanDefinition,將掃描到的bean存放到一個beanname為key、beanDefinition為value的map內
  9. getBean => getBeanFactory.getBean => doGetBean
    doCreateBean => createBeanInstance => autowireConstructor => autowireConstructor => instantiate => instantiateClass => newInstance

    1. AbstractBeanFactory
  10. 屬性注入 doCreateBean方法,填充Bean(populateBean)

 

 

 

 

  借鑒:https://segmentfault.com/a/1190000012887776#articleHeader5

 


免責聲明!

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



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