1. 程式人生 > 其它 >spring-boot原始碼分析之beanFactory · 肆

spring-boot原始碼分析之beanFactory · 肆

前言

昨天我們又分析了容器的建立過程,從容器的建立過程中,我們找到了beanFactory例項化後最基本的初始化——註冊需要忽略的介面(ignoreDependencyInterface)、註冊配置處理器(registerAnnotationConfigProcessors),beanFactory剩餘的初始化操作都在後面的方法中,今天我們先來看prepareContext,雖然在prepareContext前面還有一個getSpringFactoriesInstances方法,但是這個方法並沒有和beanFactory進行互動,所以就直接跳過了。

prepareContext

關於這個方法,我們前面已經分析過了,但基本上都是一帶而過,所以今天我們就沿著beanFactory

的初始化過程再來看下這個核心方法:

我們先來梳理下這個方法的執行流程:

  • 設定容器環境(context.setEnvironment),這一步操作基本與beanFacotry沒有關係,有的也是一些取值操作,並沒有往beanFactory中註冊資料:

  • 容器後置處理(postProcessApplicationContext),這個方法內部主要有三步操作。第一步是往beanFactory中註冊beanName生成器,但由於預設情況下這個配置為空,所以並未進行註冊操作;第二步是設定容器的資源載入器,由於resourceLoader是空,所以這裡也沒有設定;最後一步是註冊轉換服務,預設情況下會為我們註冊136

    個轉換器,這些轉換器的作用就是進行型別轉換,如果能在實際開發中用起來,那也是美滋滋了:

    可以看到預設情況下為我們註冊的轉換器包括了StringDate這種常用的轉換,當然我們也可以定義自己的轉換器,這個我記下來,後面專門出一期demo示例。

  • 初始化操作(applyInitializers),這個方法我們昨天已經分析過了,這裡就不再贅述了,後面關於ApplicationContextInitializer的初始化我也會專門做一期demo分享的。

  • 繫結容器初始化事件(contextPrepared),這個方法在容器建立並準備好之後,資源載入完成前執行,這一步和beanFactory也沒有關係

  • 列印startupInfo。下面那一段程式碼就是列印啟動日誌資訊, 預設情況下logStartupInfotrue,所以控制檯會輸出兩行日誌:

  • 獲取beanFactorycontext.getBeanFactory()),這個是為了方便後面註冊資料,因為緊接著就需要把springApplicationArgumentsspringBootBanner等註冊到beanFactory中:

    最終registerSingleton方法會把他們註冊到singletonObjects容器中,從名字我們就可以看出來,這是個存放單例物件的容器。

  • 設定是否允許同名覆蓋(setAllowBeanDefinitionOverriding),預設情況下為trueallowBeanDefinitionOverriding屬性預設值)。如果為true,後面的BeanDefinition資料會將前面的覆蓋掉。但是預設啟動時,spring boot會將它該為false

  • 新增beanFactory懶載入後置處理器(addBeanFactoryPostProcessor),由於預設情況下並未啟動懶載入,所以預設情況下懶載入後置處理器也不會被新增

  • 獲取所有資源(getAllSources),預設情況下只包括當前spring boot專案的主類,同時關聯了包括classLoaderpackages等資料

  • 將資源載入到容器中(load,官方文件給的解釋是bean)。這個方雖然看起來其貌不揚,但是內部操作還是蠻多的。本來內容已經寫出來了,但是介於篇幅我決定把剩餘內容放到明天分享,當然也是因為load方法確實也比較重要,其內部不僅包括了scanner的初始化,而且包括了filter的相關內容,這些都算是spring boot的核心內容,所以還是要儘可能詳細些。

總結

原本是打算把prepareContext的內容一次性分享完的,但是實際分享的時候,發現內容還是蠻多的,特別是load方法,一個看起來小小的方法,沒想到它的內部初始化操作還挺複雜的。不過,經過今天的梳理之後,我感覺對prepareContext認識要比之前清晰多了,而且在分析的過程中,還發現了兩個需要demo實踐的內容,相關內容的flag已經立起來了,後面就該填坑了,這也算是意外的收穫吧。

好了,今天就先到這裡吧!