Spring框架學習:Bean生命周期

目錄

SpringBean的生命周期

Bean實例屬性填充

三級緩存

常用的Aware接口

Spring IoC容器實例化Bean總結


SpringBean的生命周期

Spring Bean的生命周期是從 Bean 實例化之后,即通過反射創建出對象之后,到Bean成為一個完整對象,最終存儲到單例池中,這個過程被稱為Spring Bean的生命周期。Spring Bean的生命周期大體上分為三個階段:

  • Bean的實例化階段:Spring框架會取出BeanDefinition的信息進行判斷當前Bean的范圍是否是singleton,是否不是延遲加載的,是否不是FactoryBean等,最終將一個普通的singleton的Bean通過反射進行實例化;
  • Bean的初始化階段:Bean創建之后還僅僅是個"半成品",還需要對Bean實例的屬性進行填充、執行一些Aware接口方法、執行BeanPostProcessor方法、執行InitializingBean接口的初始化方法、執行自定義初始化init方法等。該階段是Spring最具技術含量和復雜度的階段,Aop增強功能,Spring的注解功能等。以及Bean的循環引用問題都是在這個階段體現的。
  • Bean的完成階段:經過初始化階段,Bean就成為了一個完整的Spring Bean,被存儲到單例池singletonObjects中去。即完成了Spring Bean的整個生命周期。

接下來我們著重于Bean的初始化階段進行分析,初始化過程涉及如下幾個過程:

  • Bean實例的屬性填充
  • Aware接口屬性注入
  • BeanPostProcessor的before()方法回調
  • InitializingBean接口的初始化方法回調
  • 自定義初始化方法inti回調
  • BeanPostProcessor的after()方法回調

Bean實例屬性填充

基于xml文件的實例屬性填充。

<bean id="userService" class="com.zmt.service.impl.UserServiceImpl"><property name="userDao" ref="userDao"></property><property name="name" value="張三"></property>
</bean>

在屬性注入中,存在三種情況:

  • 一種基本屬性注入,通過反射拿到set方法直接注入
  • 一種單項引用屬性注入,如UserService中需要注入UserDao,但UserDao不需要UserService,這種從容器中執行getBean方法后通過set方法反射進去,如果容器中不存在,則先創建被注入的對象后再進行諸如操作。
  • 一種雙向對象屬性注入,也就是說,UserService中需要注入UserDao,UserDao需要注入UserService。這涉及到循環引用。

下面是循環引用的問題流程圖

如果循環依賴的話,半成品的bean會被存儲在內存中,不歸Spring管控,那么在注入時,就無法從容器中獲取到對應的bean,從而導致死循環不停的創建對象。解決方法是,在Spring中添加一個存儲半成品bean的map,當無法從單例池中獲取的對象時,從半成品中的map獲取

三級緩存

所謂三級緩存,分別是單例池與兩個存儲半成品bean的map集合,在源碼中為

這三個Map集合,分別存儲的是:

  • 實例化與初始化都完成的bean,稱為一級緩存
  • 緩存半成品,且對象已經被其他對象引用了,稱為二級緩存
  • 緩存半成品,對象也未被引用,使用時在通過工廠創建bean,稱為三級緩存

UserService和UserDao循環依賴的過程結合上述三級緩存描述一下就是

  • UserService 實例化對象,但尚未初始化,將UserService存儲到三級緩存;
  • UserService 屬性注入,需要UserDao,從緩存中獲取,沒有UserDao;
  • UserDao實例化對象,但尚未初始化,將UserDao存儲到到三級緩存;
  • UserDao屬性注入,需要UserService,從三級緩存獲取UserService,UserService從三級緩存移入二級緩存;
  • UserDao執行其他生命周期過程,最終成為一個完成Bean,存儲到一級緩存,刪除二三級緩存;
  • UserService 注入UserDao;
  • UserService執行其他生命周期過程,最終成為一個完成Bean,存儲到一級緩存,刪除二三級緩存。

常用的Aware接口

Aware接口是一種框架輔助屬性注入的一種思想,其他框架中也可以看到類似的接口。框架具備高度封裝性,我們接觸到的一般都是業務代碼,一個底層功能API不能輕易的獲取到,但是這不意味著永遠用不到這些對象,如果用到了就可以使用框架提供的類似Aware的接口,讓框架給我們注入該對象。

Aware接口

回調方法

作用

ServletContextAware

setServletContext(ServletContext context)

Spring框架回調方法注入ServletContext,web環境下才生效

BeanFactoryAware

setBeanFactory(BeanFactory factory)

Spring框架回調方法注入beanFactory對象

BeanNameAware

setBeanName(String beanName)

Spring框架回調方法注入當前Bean在容器中的beanName

ApplicationContextAware

setApplicationContext(Application application)

Spring框架回調方法注入ApplicationContext對象

Spring IoC容器實例化Bean總結

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/209678.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/209678.shtml
英文地址,請注明出處:http://en.pswp.cn/news/209678.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【MyBatis系列】MyBatis字符串問題

&#x1f49d;&#x1f49d;&#x1f49d;歡迎來到我的博客&#xff0c;很高興能夠在這里和您見面&#xff01;希望您在這里可以感受到一份輕松愉快的氛圍&#xff0c;不僅可以獲得有趣的內容和知識&#xff0c;也可以暢所欲言、分享您的想法和見解。 推薦:kwan 的首頁,持續學…

SpringBoot + Spring Cloud Alibaba + Nacos實現服務管理

1、參考文檔 Spring Cloud Alibaba參考文檔 https://spring-cloud-alibaba-group.github.io/github-pages/hoxton/zh-cn/index.html Spring Cloud Alibaba官方文檔 https://github.com/alibaba/spring-cloud-alibaba/wiki/ 2、引入 Alibaba 依賴 每個 SpringBoot 都有對應的…

css中2D和3D的區別

CSS中2D和3D的主要區別在于&#xff1a; 維度不同&#xff1a;2D是二維平面&#xff0c;3D是三維空間。可視角度不同&#xff1a;2D只能從一個平面角度看&#xff0c;而3D可以在多個角度上觀察。技術難度不同&#xff1a;3D效果需要更復雜的技術支持&#xff0c;如矩陣變換&am…

javascript實現Stack(棧)數據結構

上一篇文章我們理解了List這種數據結構&#xff0c;知道了它的特點和一些使用場景&#xff0c;這篇文章我們就來看一下棧這種數據結構&#xff0c;這里的棧可不是客棧哦&#xff0c;哈哈 棧其實和List非常像&#xff0c;使用javascript實現都是基于數組來實現 嘗試理解Stack …

6種常見的JS模塊打包器

前言 JS模塊打包器是一種工具&#xff0c;它可以將多個JS文件或模塊合并成一個或多個輸出文件&#xff0c;以便在瀏覽器或其他環境中使用。 JS模塊打包器的作用有&#xff1a; 優化代碼&#xff1a;通過壓縮、混淆、刪除無用代碼等方式&#xff0c;減少代碼的體積和復雜度&…

windows系統和虛擬機上ubuntu系統通過虛擬串口進行通信

本文的目的是實現windows系統和虛擬機上安裝的ubuntu通過串口進行通信。為了直觀觀測串口收發數據的內容&#xff0c;需要在windows系統和ubuntu系統使用串口助手來進行監聽。windows系統端用的監聽工具是串口助手SSCOM&#xff0c;ubuntu系統端使用的串口助手是CuteCom。 ubu…

OpenCL學習筆記(一)開發環境搭建(win10+vs2019)

前言 異構編程開發&#xff0c;在高性能編程中有重要的&#xff0c;筆者本次只簡單介紹下&#xff0c;如何搭建簡單的開發環境&#xff0c;可以供有需要的小伙伴們開發測試使用 一、獲取opencl的sdk庫 1.使用cuda庫 若本機有Nvidia的顯卡&#xff0c;在安裝cuda庫后&#x…

如何提高大模型在超長上下文的表現?Claude實驗表明加一句prompt立即提升效果~

本文來自DataLearnerAI官方網站&#xff1a;如何提高大模型在超長上下文的表現&#xff1f;Claude實驗表明加一句prompt立即提升效果~ | 數據學習者官方網站(Datalearner)https://www.datalearner.com/blog/1051701947131881 Claude 2.1版本的模型上下文長度最高拓展到200K&am…

【Flink系列四】Window及Watermark

3.1、window 在 Flink 中 Window 可以將無限流切分成有限流&#xff0c;是處理有限流的核心組件&#xff0c;現在 Flink 中 Window 可以是時間驅動的&#xff08;Time Window&#xff09;&#xff0c;也可以是數據驅動的&#xff08;Count Window&#xff09;。 Flink中的窗口…

c jpeg YUV圖片幀分割成 8*8 塊 ,與逆向把8*8還原為幀

1. 正向分割為若干8*8 塊 下面的程序為通用程序&#xff0c;可以分割任意塊 #include <stdlib.h> #include <string.h> #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdlib.h>…

如果微軟20年前開發.net core,JAVA會不會和IE一樣倒下了

可以跨平臺&#xff0c;大量類庫&#xff0c;微軟親自操刀&#xff0c;性能一流&#xff0c;因為沒有做跨平臺&#xff0c;.NET被 python,javascript等搶了一半以上市場。 如果微軟早早的推出類似.net core這樣的跨平臺語言&#xff0c;.net程序猿還會出在這樣的尷尬局面嗎眾所…

Java基礎-開發流程以及HelloWorld程序

目錄 1. Java的開發流程2. HelloWorld 1. Java的開發流程 開發Java程序&#xff0c;需要三個步驟&#xff1a;編寫代碼&#xff0c;編譯代碼&#xff0c;運行代碼 2. HelloWorld 編寫代碼 public class HelloWorld {public static void main(String[] args) {System.out.pri…

Ribbon 饑餓加載

Ribbon默認是采用懶加載&#xff0c;即第一次訪問時才會去創建LoadBalanceClient&#xff0c;請求時間會很長而饑餓加載則會在項目啟動時創建&#xff0c;降低第一次訪問的耗時&#xff0c;通過下面配置開啟饑餓加載: 一、懶加載 Ribbon 默認為懶加載即在首次啟動Application…

代碼隨想錄二刷 |二叉樹 | 二叉樹的層序遍歷

代碼隨想錄二刷 &#xff5c;二叉樹 &#xff5c; 二叉樹的層序遍歷 題目描述解題思路代碼實現 題目描述 102.二叉樹的層序遍歷 給你二叉樹的根節點 root &#xff0c;返回其節點值的 層序遍歷 。 &#xff08;即逐層地&#xff0c;從左到右訪問所有節點&#xff09;。 示例…

Flask 最佳實踐(一)

Flask是一個輕量級而強大的Python Web框架&#xff0c;它的簡潔性和靈活性使其成為許多開發者的首選。然而&#xff0c;為了確保項目的可維護性和可擴展性&#xff0c;我們需要遵循一些最佳實踐。本文將探討Flask中一些關鍵的最佳實踐。 1. 項目結構 構建一個清晰的項目結構是…

Java實現Socket聊天室

一、網絡編程是什么&#xff1f; 在網絡通信協議下&#xff0c;不同計算機上運行的程序&#xff0c;進行數據傳輸。 應用場景&#xff1a;即時通訊、網游對戰、金融證券、國際貿易、郵件、等等。 不管是什么場景&#xff0c;都是計算機與計算機之間通過網絡進行數據傳輸。 …

軟件測試之接口測試自動化(詳解版)

本著以和大家交流如何實現高效的接口測試為出發點&#xff0c;本文包含了我在接口測試領域的一些方法和心得&#xff0c;希望大家一起討論和分享&#xff0c;內容包括但不僅限于&#xff1a; 服務端接口測試介紹接口測試自動化介紹接口測試自動化實踐關于接口測試自動化的思考…

質量工程化,交付快速化

質量和速度之間權衡讓人很難取舍&#xff0c;而通過推進質量工程&#xff0c;以系統化的方式識別和優化系統痛點&#xff0c;可以幫助團隊構建既快又好的精益軟件生產系統。原文: Quality Engineered, Speed Delivered 所有人都想要更快的速度。 但需要解決復雜問題: 權衡質量會…

Kotlin(十四) 擴展函數和運算符重載

目錄 擴展函數 語法結構 代碼示例 運算符重載 語法結構 一元操作符 二元操作符 數值類型操作符 等于和不等于操作符 比較操作符 調用操作符 擴展函數 語法結構 對于擴張函數的語法結構其實很簡單&#xff0c;你想在那個類中添加擴張函數&#xff0c;那么你就用該類…

6. Zigzag Conversion

按照下標找規律注意leetcode的運行輸出&#xff0c;如果其中一組用例出現死循環&#xff0c;輸出結果會在一個文件&#xff0c;即部分測試用例正確&#xff0c;部分錯誤且出現死循環&#xff0c;則需辨別輸出結果屬于哪一份測試用例 class Solution { public:string convert(s…