beanfactory中單例bean的初始化過程(一)

  • 2019 年 11 月 1 日
  • 筆記

Date 10.06 pm

Point

完成beanfactory中單例bean的初始化

beanFactory.preInstantiateSingletons()

  1. 拿到所有的bean定義資訊(在 beanDefinitionNames中,遍歷list
  2. 獲取到bean的定義資訊
  3. 如果這個bean不是抽象,是單例,不是懶載入的
  4. 判斷這個bean是否factorybean(判斷這個bean有沒有實現factoryBean介面),是的話,用工廠裡面的方法去創建bean。

    • 調用getbean(&beanname) 獲取到beanFactory對象。
  5. 調用getBean(beanName)創建bean
    • 調用 doGetBean()
    • transformedBeanName進入這個方法將之前工廠bean的前綴去除,將別名轉成正式的名稱
    • getSingleton檢測單例快取中是否有已構建的單實例bean,有就直接返回這個單例bean

      /** Cache of singleton objects: bean name to bean instance. */  private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);

      所有實例過的單例bean都會在這註冊,檢查的時候還會判斷當前bean有沒有在創建過程中。如果有的話,會在earlySingletonObjects去獲取,要是這個還是沒有獲取到的話,會去singletonFactories這個map中去獲取,要是獲取到的話就刪除singletonFactories中的bean,轉而在earlySingletonObjects這個map裡面去註冊

    • 沒有獲取到bean(開始創建bean的流程)
      • 就先判斷下我們是不是正在創建這個bean的實例,避免循環引用的問題。
      • 獲取bean的父工廠(這個主要是如果有Springmvc的話 可能會有這種父子工廠)這個父工廠要是能獲取到的話,又會去調用父工廠的dogetbean方法,獲取不到父工廠的話直接下一步
      • 標記當前bean已經創建,大概就是把當前beanname放到Collections.newSetFromMap(new ConcurrentHashMap<>(256))裡面,防止多執行緒的時候多次創建單例bean
      • 獲取bean的定義資訊
      • 獲取bean所依賴的其他bean,如果有,還是調用getbean的方式去構建那些依賴的bean
      • 如果這個bean是單例bean,回掉createBean,開始單例bean創建
        • 拿到bean的定義資訊
        • 解析bean的定義的類型,檢查這個定義資訊中的beanClass是不是為空
        • 檢測是否有bean方法被重寫,有的話準備重寫這個bean方法(也是檢查bean定義資訊裡面的methodOverrides這個屬性有沒有值)
        • 讓BeanPostProcessor提前攔截,返回代理對象resolveBeforeInstantiation()
          • 先根據定義資訊中的beforeInstantiationResolved判斷初始化之前有沒有處理,有的話就不進入這個processor中了,
          • 然後判斷這個值是不是由application定義的 和 判斷當前factory中已經有了InstantiationAwareBeanPostProcessor這個processor了,然後去獲取這個bean的目標class,然後調用InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation啟動前置處理器,然後如果返回的bean有值的話,再調用applyBeanPostProcessorsAfterInitialization後置處理器,然後將bean定義資訊中beforeInstantiationResolved這個參數賦值成這個返回的bean,然後返回這個bean

https://github.com/fulln