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

Date 10.06 pmhtml

Point

完成beanfactory中單例bean的初始化

beanFactory.preInstantiateSingletons()

  1. 拿到全部的bean定義信息(在 beanDefinitionNames中,遍歷listjava

  2. 獲取到bean的定義信息git

  3. 若是這個bean不是抽象,是單例,不是懶加載的github

  4. 判斷這個bean是否factorybean(判斷這個bean有沒有實現factoryBean接口),是的話,用工廠裏面的方法去建立bean。緩存

    • 調用getbean(&beanname) 獲取到beanFactory對象。
  5. 調用getBean(beanName)建立bean多線程

    • 調用 doGetBean()mvc

    • transformedBeanName進入這個方法將以前工廠bean的前綴去除,將別名轉成正式的名稱app

    • getSingleton檢測單例緩存中是否有已構建的單實例bean,有就直接返回這個單例beanide

      /** 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裏面去註冊post

    • 沒有獲取到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

原文出處:https://www.cnblogs.com/wzqshb/p/11774767.html

相關文章
相關標籤/搜索