spring 相關知識

1、Spring中bean的加載過程?
首先從大的幾個核心步驟來去說明,因爲Spring中的具體加載過程和用到的類實在是太多了。
(1)、首先是先從AbstractBeanFactory中去調用doGetBean(name, requiredType, final Object[] args, boolean typeCheckOnly【這個是判斷進行創建bean還是僅僅用來做類型檢查】)方法,然後第一步要做的就是先去對傳入的參數name進行做轉換,因爲有可能傳進來的name=“&XXX”之類,需要去除&符號
(2)、然後接着是去調用getSingleton()方法,其實在上一個面試題中已經提到了這個方法,這個方法就是利用“三級緩存” 來去避免循環依賴問題的出現的。【這裏補充一下,只有在是單例的情況下才會去解決循環依賴問題】
(3)、對從緩存中拿到的bean其實是最原始的bean,還未長大,所以這裏還需要調用getObjectForBeanInstance(Object beanInstance, String name, String beanName, RootBeanDefinition mbd)方法去進行實例化。
(4)、然後會解決單例情況下嘗試去解決循環依賴,如果isPrototypeCurrentlyInCreation(beanName)返回爲true的話,會繼續下一步,否則throw new BeanCurrentlyInCreationException(beanName);
(5)、因爲第三步中緩存中如果沒有數據的話,就直接去parentBeanFactory中去獲取bean,然後判斷containsBeanDefinition(beanName)中去檢查已加載的XML文件中是否包含有這樣的bean存在,不存在的話遞歸去getBean()獲取,如果沒有繼續下一步
(6)、這一步是吧存儲在XML配置文件中的GernericBeanDifinition轉換爲RootBeanDifinition對象。這裏主要進行一個轉換,如果父類的bean不爲空的話,會一併合併父類的屬性
(7)、這一步核心就是需要跟這個Bean有關的所有依賴的bean都要被加載進來,通過剛剛的那個RootBeanDifinition對象去拿到所有的beanName,然後通過registerDependentBean(dependsOnBean, beanName)註冊bean的依賴
(8)、然後這一步就是會根據我們在定義bean的作用域的時候定義的作用域是什麼,然後進行判斷在進行不同的策略進行創建(比如isSingleton、isPrototype)
(9)、這個是最後一步的類型裝換,會去檢查根據需要的類型是否符合bean的實際類型去做一個類型轉換。Spring中提供了許多的類型轉換器

2、Spring中bean的生命週期?

 

在這裏插入圖片描述

 

  1. 首先會先進行實例化bean對象
  2. 然後是進行對bean的一個屬性進行設置
  3. 接着是對BeanNameAware(其實就是爲了讓Spring容器來獲取bean的名稱)、BeanFactoryAware(讓bean的BeanFactory調用容器的服務)、ApplicationContextAware(讓bean當前的applicationContext可以來取調用Spring容器的服務)
  4. 然後是實現BeanPostProcessor 這個接口中的兩個方法,主要是對調用接口的前置初始化postProcessBeforeInitialization
  5. 這裏是主要是對xml中自己定義的初始化方法 init-method = “xxxx”進行調用
  6. 然後是繼續對BeanPostProcessor 這個接口中的後置初始化方法進行一個調用postProcessAfterInitialization()
  7. 其實到這一步,基本上這個bean的初始化基本已經完成,就處於就緒狀態
  8. 然後就是當Spring容器中如果使用完畢的話,就會調用destory()方法
  9. 最後會去執行我們自己定義的銷燬方法來進行銷燬,然後結束生命週期

補充:當在執行第六步之後,如果Spring初始的這個bean的作用域是Prototype的話,之後的過程就不歸Spring來去管理了,直接就交給用戶就可以了。
 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章