日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring bean的生命流程

發布時間:2025/7/14 javascript 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring bean的生命流程 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

2019獨角獸企業重金招聘Python工程師標準>>>

Spring 是一個輕量級的 J2EE 開源框架,其目標是降低企業級應用開發難度,提高企業級應用開發效率。在日程開發中,我們會經常使用 Spring 框架去構建應用。所以作為一個經常使用的框架,了解其原理還是很有必要的。接下來我們就從宏觀層面上,來看看 Spring 中的 bean 由實例化到銷毀的過程。在詳細討論 bean 生命周期前,先上一張圖,后面也會圍繞這張圖展開討論。

圖1 bean實例化過程

接下來對照上圖,一步一步對 singleton 類型 bean 的生命周期進行解析:

  • 實例化 bean 對象,類似于 new XXObject()
  • 將配置文件中配置的屬性填充到剛剛創建的 bean 對象中。
  • 檢查 bean 對象是否實現了 Aware 一類的接口,如果實現了則把相應的依賴設置到 bean 對象中。比如如果 bean 實現了 BeanFactoryAware 接口,Spring 容器在實例化bean的過程中,會將 BeanFactory 容器注入到 bean 中。
  • 調用 BeanPostProcessor 前置處理方法,即 postProcessBeforeInitialization(Object bean, String beanName)。
  • 檢查 bean 對象是否實現了 InitializingBean 接口,如果實現,則調用 afterPropertiesSet 方法。或者檢查配置文件中是否配置了 init-method 屬性,如果配置了,則去調用 init-method 屬性配置的方法。
  • 調用 BeanPostProcessor 后置處理方法,即 postProcessAfterInitialization(Object bean, String beanName)。我們所熟知的 AOP 就是在這里將 Adivce 邏輯織入到 bean 中的。
  • 注冊 Destruction 相關回調方法。
  • bean 對象處于就緒狀態,可以使用了。
  • 應用上下文被銷毀,調用注冊的 Destruction 相關方法。如果 bean 實現了 DispostbleBean 接口,Spring 容器會調用 destroy 方法。如果在配置文件中配置了 destroy 屬性,Spring 容器則會調用 destroy 屬性對應的方法。
  • 上述流程從宏觀上對 Spring 中 singleton 類型 bean 的生命周期進行了描述,接下來說說所上面流程中的一些細節問題。
    先看流程中的第二步 -- 設置對象屬性。在這一步中,對于普通類型的屬性,例如 String,Integer等,比較容易處理,直接設置即可。但是如果某個 bean 對象依賴另一個 bean 對象,此時就不能直接設置了。Spring 容器首先要先去實例化 bean 依賴的對象,實例化好后才能設置到當前 bean 中。大致流程如下:

    圖2 依賴實例化流程圖

    上面圖片描述的依賴比較簡單,就是 BeanA 依賴 BeanB。現在考慮這樣一種情況,BeanA 依賴 BeanB,BeanB 依賴 BeanC,BeanC 又依賴 BeanA。三者形成了循環依賴,如下所示:

    圖3 循環依賴

    對于這樣的循環依賴,根據依賴注入方式的不同,Spring 處理方式也不同。如果依賴靠構造器方式注入,則無法處理,Spring 直接會報循環依賴異常。這個理解起來也不復雜,構造 BeanA 時需要 BeanB 作為構造器參數,此時 Spring 容器會先實例化 BeanB。構造 BeanB 時,BeanB 又需要 BeanC 作為構造器參數,Spring 容器又不得不先去構造 BeanC。最后構造 BeanC 時,BeanC 又依賴 BeanA 才能完成構造。此時,BeanA 還沒構造完成,BeanA 要等 BeanB 實例化好才能完成構造,BeanB 又要等 BeanC,BeanC 等 BeanA。這樣就形成了死循環,所以對于以構造器注入方式的循環依賴是無解的,Spring 容器會直接報異常。對于 setter 類型注入的循環依賴則可以順利完成實例化并依次注入,這里具體細節就不說了,詳細可以參考《Spring源碼深度解析》一書相關章節。

    循環依賴問題說完,接下來 bean 實例化流程中的第6步 -- 調用 BeanPostProcessor 后置處理方法。先介紹一下 BeanPostProcessor 接口,BeanPostProcessor 接口中包含了兩個方法,其定義如下:

    public interface BeanPostProcessor {Object postProcessBeforeInitialization(Object bean, String beanName) throws Exception;Object postProcessAfterInitialization(Object bean, String beanName) throws Exception; }

    BeanPostProcessor 是一個很有用的接口,通過實現接口我們就可以插手 bean 的實例化過程,為拓展提供了可能。我們所熟知的 AOP 就是在這里進行織如入,具體點說是在 postProcessAfterInitialization(Object bean, String beanName) 執行織入邏輯的。下面就來說說 Spring AOP 織入的流程,以及 AOP 是怎樣和 IOC 整合的。先說 Spring AOP 織入流程,大致如下:

  • 查找實現了 PointcutAdvisor 類型的切面類,切面類包含了 Pointcut 和 Advice 實現類對象。
  • 檢查 Pointcut 中的表達式是否能匹配當前 bean 對象。
  • 如果匹配到了,表明應該對此對象織入 Advice。
  • 將 bean,bean class對象,bean實現的interface的數組,Advice對象傳給代理工廠 ProxyFactory。代理工廠創建出 AopProxy 實現類,最后由 AopProxy 實現類創建 bean 的代理類,并將這個代理類返回。此時從 postProcessAfterInitialization(Object bean, String beanName) 返回的 bean 此時就不是原來的 bean 了,而是 bean 的代理類。原 bean 就這樣被無感的替換掉了,是不是有點偷天換柱的感覺。
  • 大家現在應該知道 AOP 是怎樣作用在 bean 上的了,那么 AOP 是怎樣和 IOC 整合起來并協同工作的呢?下面就來簡單說一下。

    Spring AOP 生成代理類的邏輯是在 AbstractAutoProxyCreator 相關子類中實現的,比如 DefaultAdvisorAutoProxyCreator、AspectJAwareAdvisorAutoProxyCreator 等。上面說了 BeanPostProcessor 為拓展留下了可能,這里 AbstractAutoProxyCreator 就將可能變為了現實。AbstractAutoProxyCreator 實現了 BeanPostProcessor 接口,這樣 AbstractAutoProxyCreator 可以在 bean 初始化時做一些事情。光繼承這個接口還不夠,繼承這個接口只能獲取 bean,要想讓 AOP 生效,還需要拿到切面對象(包含 Pointcut 和 Advice)才行。所以 AbstractAutoProxyCreator 同時繼承了 BeanFactoryAware 接口,通過實現該接口,AbstractAutoProxyCreator 子類就可拿到 BeanFactory,有了 BeanFactory,就可以獲取 BeanFactory 中所有的切面對象了。有了目標對象 bean,所有的切面類,此時就可以為 bean 生成代理對象了。

    圖4 AbstractAutoProxyCreator繼承圖(刪掉了一些不關心的繼承分支)

    到這里,從宏觀上已經對 bean 的生命流程進行了較為詳細的描述。由于暫時能力有限,只能從宏觀上分析,以前嘗試過去看 Spring IOC 的實現代碼,感覺還是太復雜了,細節太多,跟蹤了十幾二十個方法后就開始凌亂了。在幾次失敗的嘗試后,終于放棄了。后來總結了一下失敗的原因,當時自己剛工作不是很久,代碼寫的少,經驗不足。并且在對 Spring 很多特性不熟悉的情況下就去看 Spring 源碼,結果只能到處碰壁,陷入 Spring 各種細節之中久久不能自拔?。所以對于想看某個框架代碼的同學,一定要在熟練使用這個框架的基礎上再去看。不要像我這樣急于求成,不然到最后只能失敗啊。本人這篇博客建立在仿寫了 Spring IOC 和 AOP的基礎上寫出來的,在仿寫過程中參考了黃億華前輩的?tiny-spring?項目,有興趣的同學可以讀讀 tiny-spring。我自己仿寫的項目也放在了github上,傳送門 -->?toy-spring。

    本篇博客到此結束,如果有寫錯的地方,歡迎指出來,謝謝!如果錯誤的地方對你造成了困擾,我表示很抱歉。

    參考?

    • 《Spring揭秘》
    • 《Spring源碼深度解析》
    • https://www.zybuluo.com/dugu9sword/note/382745

    轉載于:https://my.oschina.net/u/2935389/blog/3032887

    總結

    以上是生活随笔為你收集整理的Spring bean的生命流程的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。