1. 程式人生 > >Spring原始碼窺探之:單例項Bean的建立過程

Spring原始碼窺探之:單例項Bean的建立過程

finishBeanFactoryInitialization(beanFactory);初始化剩下的所有的單例項(非懶載入)Bean(Instantiate all remaining (non-lazy-init) singletons.)

1. beanFactory.preInstantiateSingletons();初始化剩下的所有的單例項(非懶載入)Bean

  1) 首先獲取所有BeanDefinition的名字List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

  2) 根據名字獲取Bean的定義資訊RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);

  3) 再依次判斷RootBeanDefinition不是抽象的,是單例的,不是懶載入的

    1> 判斷是不是工廠Bean,isFactoryBean(beanName),如果是的話,利用工廠來建立物件

    2> 如果不是,就用getBean(beanName);來建立物件.

      0. getBean(beanName)

      1. doGetBean(name, null, null, false);

      2. 先從快取中獲取單例項Bean,如果能獲取到說明這個Bean建立過(所有建立過的單例項Bean都會被快取起來)

      Object sharedInstance = getSingleton(beanName);

      /** Cache of singleton objects: bean name --> bean instance */

      private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

      3. 快取中沒有的話,就來建立物件.

      4. 標記當前Bean已被建立

      5. 獲取Bean的定義資訊

      6. 獲取當前Bean依賴的其它Bean(dependsOn),如果有按照getBean()把依賴的Bean先創建出來。

      7. 啟動單例項Bean的建立流程

        1)createBean(beanName,mbd,args)

        2)Object bean = resolveBeforeInstantiation(beanName, mbdToUse);讓BeanPostProcessor先攔截返回代理物件

          InstantiationAwareBeanPostProcessor提前執行:

          先觸發InstantiationAwareBeanPostProcessor介面中的postProcessBeforeInstantiation(beanClass, beanName);

          如果有返回值,那麼再觸發InstantiationAwareBeanPostProcessor中的postProcessAfterInitialization(result, beanName);

        3)如果InstantiationAwareBeanPostProcessor沒有返回代理物件

        4)Object beanInstance = doCreateBean(beanName, mbdToUse, args);建立Bean

          1. 【建立Bean的例項】instanceWrapper = createBeanInstance(beanName, mbd, args);建立Bean

            利用工廠方法或者構造器來建立Bean的例項

          2. applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);

            呼叫MergedBeanDefinitionPostProcessor的bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);