Spring Bean的生命周期與作用域詳解

一、Spring Bean的生命周期

Spring Bean的生命周期指的是Bean從創建到銷毀的整個過程。理解這個生命周期對于正確使用Spring框架至關重要,它可以幫助我們在適當的時機執行自定義邏輯。

1. 完整的Bean生命周期階段

Spring Bean的生命周期可以分為以下幾個主要階段:

  1. 實例化(Instantiation):容器通過構造函數或工廠方法創建Bean實例

  2. 屬性填充(Populate properties):設置Bean的屬性值和依賴

  3. BeanNameAware.setBeanName():如果實現了BeanNameAware接口

  4. BeanFactoryAware.setBeanFactory():如果實現了BeanFactoryAware接口

  5. ApplicationContextAware.setApplicationContext():如果實現了ApplicationContextAware接口

  6. BeanPostProcessor.postProcessBeforeInitialization():BeanPostProcessor的前置處理

  7. @PostConstruct注解的方法:執行初始化回調

  8. InitializingBean.afterPropertiesSet():如果實現了InitializingBean接口

  9. 自定義init-method:執行配置的初始化方法

  10. BeanPostProcessor.postProcessAfterInitialization():BeanPostProcessor的后置處理

  11. Bean就緒可用:此時Bean可以被正常使用

  12. @PreDestroy注解的方法:容器關閉時執行銷毀回調

  13. DisposableBean.destroy():如果實現了DisposableBean接口

  14. 自定義destroy-method:執行配置的銷毀方法

2. 生命周期示例代碼

public class ExampleBean implements BeanNameAware, InitializingBean, DisposableBean {private String name;public ExampleBean() {System.out.println("1. 實例化Bean");}public void setName(String name) {System.out.println("2. 設置屬性值");this.name = name;}@Overridepublic void setBeanName(String name) {System.out.println("3. BeanNameAware.setBeanName()");}@PostConstructpublic void postConstruct() {System.out.println("5. @PostConstruct方法");}@Overridepublic void afterPropertiesSet() {System.out.println("6. InitializingBean.afterPropertiesSet()");}public void customInit() {System.out.println("7. 自定義init-method");}@PreDestroypublic void preDestroy() {System.out.println("9. @PreDestroy方法");}@Overridepublic void destroy() {System.out.println("10. DisposableBean.destroy()");}public void customDestroy() {System.out.println("11. 自定義destroy-method");}
}// 配置類
@Configuration
public class AppConfig {@Bean(initMethod = "customInit", destroyMethod = "customDestroy")public ExampleBean exampleBean() {ExampleBean bean = new ExampleBean();bean.setName("示例Bean");return bean;}
}

3. 生命周期流程圖

實例化Bean → 設置屬性 → Aware接口回調 → BeanPostProcessor前置處理 → 
@PostConstruct → afterPropertiesSet → init-method → 
BeanPostProcessor后置處理 → Bean就緒可用 → 
@PreDestroy → destroy() → destroy-method

二、Spring Bean的作用域

Spring框架支持多種Bean作用域,允許開發者根據需求控制Bean的創建方式和生命周期。

1. 標準作用域

Spring提供了以下標準作用域:

  1. singleton(單例,默認)

    • 每個Spring IoC容器中一個Bean定義對應一個實例

    • 所有對該Bean的請求都返回同一個實例

    • 生命周期與容器相同

  2. prototype(原型)

    • 每次請求都創建一個新的Bean實例

    • 適用于有狀態的Bean

    • Spring不管理完整的生命周期,只負責初始化

  3. request(請求)

    • 每個HTTP請求創建一個新的Bean

    • 僅適用于Web應用

    • 請求結束時銷毀

  4. session(會話)

    • 每個HTTP會話創建一個Bean

    • 僅適用于Web應用

    • 會話結束時銷毀

  5. application(應用)

    • 每個ServletContext生命周期創建一個Bean

    • 類似單例,但范圍是ServletContext而非Spring容器

  6. websocket(WebSocket)

    • 每個WebSocket會話創建一個Bean

    • 僅適用于WebSocket應用

2. 作用域配置示例

XML配置方式:
<bean id="accountService" class="com.example.AccountService" scope="prototype"/>
Java注解方式:
@Bean
@Scope("prototype")
public AccountService accountService() {return new AccountService();
}
使用@Scope注解:
@Service
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class PrototypeService {// ...
}

3. 作用域選擇建議

  1. 無狀態服務:使用singleton(默認),性能最佳

  2. 有狀態組件:使用prototype,避免并發問題

  3. Web相關數據:根據需要使用request、session等作用域

  4. 線程安全考慮:prototype作用域可以避免線程安全問題,但會增加創建開銷

4. 自定義作用域

Spring還允許注冊自定義作用域:

public class ThreadScope implements Scope {// 實現Scope接口方法
}// 注冊自定義作用域
ConfigurableBeanFactory factory = (ConfigurableBeanFactory) applicationContext.getAutowireCapableBeanFactory();
factory.registerScope("thread", new ThreadScope());// 使用自定義作用域
@Bean
@Scope("thread")
public MyBean myBean() {return new MyBean();
}

三、生命周期與作用域的關系

不同作用域的Bean生命周期有所不同:

  1. singleton

    • 容器啟動時初始化(默認懶加載除外)

    • 容器關閉時銷毀

    • 完整的生命周期回調

  2. prototype

    • 每次請求時初始化

    • 容器不跟蹤實例,不會調用銷毀方法

    • 只有部分生命周期回調

  3. request/session

    • 請求/會話開始時初始化

    • 請求/會話結束時銷毀

    • 完整的生命周期回調

四、最佳實踐

  1. 盡量使用singleton作用域:性能最佳,適用于無狀態服務

  2. 謹慎使用prototype:僅在必要時使用,注意資源釋放

  3. 合理使用生命周期回調:資源初始化/釋放放在合適的回調中

  4. 避免在singleton中注入prototype:會導致prototype失去意義,可以使用方法注入解決

  5. Web作用域Bean不要注入singleton:會導致狀態不一致

五、總結

理解Spring Bean的生命周期和作用域對于開發高質量的Spring應用至關重要。通過合理利用生命周期回調和選擇適當的作用域,可以構建出既高效又可靠的應用程序。記住,大多數情況下默認的singleton作用域是最佳選擇,只有在確實需要時才使用其他作用域。

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

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

相關文章

如何將Excel表的內容轉化為json格式呢?

文章目錄 一、前言二、具體操作步驟 一、前言 先說一下我使用Excel表的內容轉為json的應用場景&#xff0c;我們是用來處理國際化的時候用到的。 二、具體操作步驟 第一步&#xff1a;選擇要轉化Excel表的內容&#xff08;必須是key&#xff0c;value形式的&#xff09; 第二…

內存堆棧管理(Linux)

以問題形式講解 1.每一個進程都有一個堆空間嗎&#xff1f;還是多個進程共用一個堆空間&#xff1f; 在操作系統中&#xff0c;??每個進程都有自己獨立的虛擬地址空間&#xff0c;其中包括自己獨占的堆空間。堆空間是進程私有的&#xff0c;不與其他進程共享。 進程之間的內…

ThreatLabz 2025 年人工智能安全報告

AI 應用趨勢&#xff1a;爆發式增長與風險并存 2024 年&#xff0c;全球企業的 AI/ML 工具使用量呈指數級增長。Zscaler 云平臺數據顯示&#xff0c;2024 年 2 月至 12 月期間&#xff0c;AI/ML 交易總量達 5365 億次&#xff0c;同比激增 3464.6%&#xff0c;涉及 800 多個應…

【Oracle學習筆記】7.存儲過程(Stored Procedure)

Oracle中的存儲過程是一組為了完成特定功能而預先編譯并存儲在數據庫中的SQL語句和PL/SQL代碼塊。它可以接受參數、執行操作&#xff08;如查詢、插入、更新、刪除數據等&#xff09;&#xff0c;并返回結果。以下從多個方面詳細講解&#xff1a; 1. 存儲過程的創建 創建存儲過…

tc工具-corrupt 比 delay/loss 更影響性能

1. netem corrupt 5% 的作用 功能說明 corrupt 5% 表示 隨機修改 5% 的數據包內容&#xff08;如翻轉比特位&#xff09;&#xff0c;模擬數據損壞。它本身不會直接丟棄或延遲數據包&#xff0c;而是讓接收端收到錯誤的數據&#xff08;可能觸發校驗和失敗、協議層重傳等&…

Flask YAML管理工具

項目概述 項目地址&#xff1a;https://github.com/KaiqiZing/Flask_Yaml_Demo 這是一個基于Flask開發的YAML文件管理工具&#xff0c;提供了完整的YAML文件查看、編輯、管理功能&#xff0c;具有現代化的Web界面和強大的編輯能力。 核心功能 1. 文件管理功能 目錄掃描&am…

Embedding模型微調實戰(ms-swift框架)

目錄 簡介 1. 創建虛擬環境 2 安裝ms-swift 3安裝其他依賴庫 4. 下載數據集 5.開始embedding模型訓練 6. 自定義數據格式和對應的Loss類型 &#xff08;1&#xff09; infoNCE損失 (2)余弦相似度損失 (3)對比學習損失 &#xff08;4).在線對比學習損失 &#…

從性能優化賽到社區Committer,走進趙宇捷在Apache Fory的成長之路

Apache Fory 是一個基于JIT和零拷貝的高性能多語言序列化框架&#xff0c;實現了高效緊湊的序列化協議&#xff0c;提供極致的性能、壓縮率和易用性。在多語言序列化框架技術領域取得了重大突破&#xff0c;推動序列化技術步入高性能易用新篇章&#xff01;這一切&#xff0c;都…

Python實例題:基于 Flask 的任務管理系統

目錄 Python實例題 題目 要求&#xff1a; 解題思路&#xff1a; 代碼實現&#xff1a; Python實例題 題目 基于 Flask 的任務管理系統 要求&#xff1a; 使用 Flask 框架構建一個任務管理系統&#xff0c;支持以下功能&#xff1a; 用戶認證&#xff08;注冊、登錄、…

利用GPU加速TensorFlow

一、寫在前面 我們已經依靠keras和TensorFlow給大家做了一些機器學習在圖像處理中的應用(影像組學學習手冊,基于深度學習的圖像分類任務)&#xff0c;此前的教程中我們沒有用GPU進行加速&#xff0c;但是相較于CPU而言&#xff0c;GPU是設計用于處理大規模并行計算任務的硬件&…

模型預測專題:強魯棒性DPCC

0 1 前言 在進行DPCC的學習過程中&#xff0c;于下面鏈接看到了一篇強魯棒性算法&#xff1b;感覺挺有意思的&#xff0c;學習一下。 永磁同步電機高性能控制算法&#xff08;12&#xff09;——基于預測電流誤差補償的強魯棒預測控制/參數辨識&有限集預測控制與連續集預…

修復opensuse 風滾草rabbitmq的Error: :plugins_dir_does_not_exist問題

https://wiki.archlinux.org/title/Talk:RabbitMQ 報錯 yqh192 /u/l/r/l/r/plugins> sudo rabbitmq-plugins enable rabbitmq_management Error: :plugins_dir_does_not_exist Arguments given:enable rabbitmq_managementUsagerabbitmq-plugins [--node <node>] [--…

前端做gis地圖有哪些庫

以下是前端開發GIS地圖常用的庫&#xff1a; Leaflet&#xff1a;輕量級、易于使用的開源JavaScript庫&#xff0c;具有豐富的地圖功能和插件生態系統&#xff0c;支持多種地圖數據源&#xff0c;適合初學者和專業開發者。其優勢在于簡潔性和易用性&#xff0c;代碼結構清晰&am…

賦能城市安全韌性|眾智鴻圖總裁扈震受邀出席智慧城市大會發表主題報告

——“眾智鴻圖作為城市基礎設施智能化綜合服務提供商&#xff0c;以地理信息科學、時空大數據、人工智能為核心能力&#xff0c;長期深耕于燃氣、供水、排水等城市基礎設施生命線領域及港口、園區等工業領域&#xff0c;致力于為城市穩定運行與高效發展提供堅實保障。” 2025年…

【大語言模型入門】—— 淺析LLM基座—Transformer原理

【大語言模型入門】—— 淺析LLM基座—Transformer原理 解密GPT核心技術&#xff1a;Transformer架構深度解析被反復強調的核心概念意味著什么&#xff1f; GPT預測機制解析&#xff1a;從Next Token Prediction到任務推理核心機制的本質案例驅動的機制解析解構策略&#xff1a…

Django打造智能Web機器人控制平臺

Django 實現 Web 機器人控制 以下是關于 Django 實現 Web 機器人控制管理的實例思路和關鍵代碼片段,涵蓋多個常見場景。由于篇幅限制,剩余的可通過類似模式擴展。 基礎機器人模型定義 # models.py from django.db import modelsclass Robot(models.Model):name = models.C…

周賽98補題

題目意思&#xff1a; 給定一個數字判斷加上自身任意因子數&#xff0c;是否能成為一個奇數。 思路&#xff1a; 我們想一個最簡單的判斷方法&#xff0c; 任意的數字的因子數都有1&#xff0c;故&#xff0c;最簡單的方法就是判斷奇偶。 奇數1成偶數&#xff0c;偶數1成奇…

【STM32】 STM32低功耗模式詳解:睡眠模式與喚醒機制【待測試】

本篇知識點基于F0講解 一、STM32三種低功耗模式參考表格 模式功耗喚醒時間保持狀態典型應用場景睡眠模式中等 (mA級)最短 (μs級)CPU停止&#xff0c;外設保持短暫待機&#xff0c;快速響應停止模式低 (μA級)中等 (ms級)RAM保持&#xff0c;時鐘停止長時間待機&#xff0c;電…

【Vue入門學習筆記】Vue核心語法

目錄 準備工作刪除不需要的代碼 模版語法文本插值使用JavaScript表達式無效寫法原始HTML 屬性綁定簡寫布爾型Attribute動態綁定多個值 準備工作 刪除不需要的代碼 刪除components下的文件 進入App.vue 刪掉代碼&#xff0c;只保留如下內容 <template></template&g…

ClickHouse 窗口分析 argMax() / argMin()

argMin() 是 ClickHouse 中一個非常有用的聚合函數&#xff0c;它可以找出某個列的最小值&#xff0c;并返回該最小值對應的另一個列的值 函數語法 argMin(arg, val) arg&#xff1a;要返回的列&#xff08;當找到最小值時返回該列的值&#xff09; val&#xff1a;用于比較的…