spring Bean創建的完整過程記錄
前言
復習一下spring實現IOC的源碼流程準備工作:
強烈建議大傢從git上拉取spring源碼來學習Spring源碼。因為裡面相較於IDEA生成的會有註釋,裡面有的方法會有註釋看起來會省力一點。
以下都是用5.0.2版本來做闡述。
bean創建的流程圖
寫在前面:建議大傢一定要自己用實例跑一遍,做好記錄。如果隻是看看會非常抽象。此流程圖作為梗概,便於加強記憶和理解,新手或無基礎的有個印象即可。等跟隨本文走通一遍,在回過頭看這個圖,或許會有收獲
源碼走一遍bean的定義這是我的bean目錄結構,隻是做一個例子
獲取核心容器對象,bean最後都會放在此容器對象中
* ApplicationContext的三個實現類 * ClassPathXmlApplicationContext 它可以加載類路徑下的配置文件,要求必須在類路徑下 * FileSystemXmlApplicationContext 可以加載任意路徑下的配置文件,必須有訪問權限 * AnnotationConfigApplicationContext 用於讀取註解創建容器的 這裡我用ClassPathXmlApplicationContext來做演示 public class MyTest { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml"); } }
快速開始
建議用IDEA的debug模式來觀察Spring的IOC過程
進入到此類的構造方法中
查看setConfigLocations,就是將配置文件加載到configLocations裡去
向下執行,查看refresh()
this.prepareRefresh(): 此方法是準備工作,大傢感興趣可以點進去看一下,可以看到裡面是獲取時間,獲取環境信息的一些設置。
this.obtainFreshBeanFactory(): 這一步是創建beanFactory,並且讀取Bean的信息,源碼註釋中還有寫到
// Tell the subclass to refresh the internal bean factory.會告訴子類去刷新內部bean工廠
this.refreshBeanFactory:
* This implementation performs an actual refresh of this context's underlying * bean factory, shutting down the previous bean factory (if any) and * initializing a fresh bean factory for the next phase of the context's lifecycle. 這個實現類的方法會刷新容器中的beanFactory,關閉之前存在的並且初始化新的beanFactory
利用this.createBeanFactory() 創建瞭一個beanFactory,類型為DefaultListableBeanFactory
這個類接著往下走:this.loadBeanDefinitions(beanFactory);
* Load bean definitions into the given bean factory, typically through * delegating to one or more bean definition readers. 這個方法會將beandefinitionsReader讀取到的bean definitions放入bean工廠,我們以上提出的三種 註入方式都會走到這裡,將bean信息丟進去
返回上述 refresh()
this.prepareBeanFactory(beanFactory); 設置和忽略一些對象值
this.postProcessBeanFactory(beanFactory); 空方法可自定義擴展
this.invokeBeanFactoryPostProcessors(beanFactory);
* Instantiate and invoke all registered BeanFactoryPostProcessor beans, * respecting explicit order if given. * <p>Must be called before singleton instantiation. 實例化所有beanFactory組件
registerBeanPostProcessors(beanFactory);
Instantiate and register all BeanPostProcessor beans, //先註冊再調用
initApplicationEventMulticaster(); 觀察者模式監聽器, 監聽組件的相關狀態,並決定相關調用方法。
finishBeanFactoryInitialization(beanFactory); 重要!!
* Finish the initialization of this context's bean factory, * initializing all remaining singleton beans. 完成瞭容器bean factory的初始化,並且初始化其他的bean單例對象
beanFactory.preInstantiateSingletons(); 實例化方法
此方法最後this.getBean(beanName)
繼續
Return an instance, which may be shared or independent, of the specified bean. 註釋已經很清楚瞭,此方法會返回一個實例,就是我們的bean對象
進入到createBean方法中
繼續進入
繼續進入
Instantiate the given bean using its default constructor. 這個方法註釋說明瞭實例化對象是用構造器完成的
繼續看他如何構造的
ca 就是Constructor,從這裡我們基本可以看出容器內,bean對象的實例化 是利用反射的基本原理,獲取類構造器,然後newInstance來實現的
以上就是bean對象實例化的基本過程,下面是實例化完成後的初始化過程
回到這裡,實例化完成後
註釋說明瞭在populateBean完成bean的初始化
繼續
會看到在此方法裡會調用前置和後置處理器來初始化Bean
以上就完成瞭bean的實例化過程,文章開頭的那個圖剛開始有點懵,但是一旦跑完一遍bean的實例化過程,再次結合圖,就清晰瞭很多。本文隻是簡單的跟隨debug順序,完整的走瞭一遍bean實例化的過程,還有特殊情況並沒有討論,後期會重新用新文章再來拓展。
如有不足還請指正。
總結
到此這篇關於spring Bean創建的文章就介紹到這瞭,更多相關Spring Bean創建過程內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- Spring5學習之基礎知識總結
- Java Spring框架創建項目與Bean的存儲與讀取詳解
- Spring 加載多個xml配置文件的原理分析
- spring IOC控制反轉原理詳解
- Spring的IOC控制反轉詳解