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方法中
繼續進入![image-20200714221630608](/Users/hjj/Library/Application Support/typora-user-images/image-20200714221630608.png)
繼續進入
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控制反轉詳解