InitializingBean接口和@PostConstruct-筆記

1. InitializingBean 簡介

1.1 功能簡介

InitializingBean?是 Spring 框架中的一個接口,用在 Bean 初始化后執行自定義邏輯。它提供了?afterPropertiesSet()?方法,該方法在以下時機被 Spring 容器自動調用:

  1. 屬性注入完成后(即所有通過?setter?方法或構造函數注入的屬性已設置完畢)。
  2. Bean 初始化階段的最后一步(在調用?@PostConstruct?注解的方法之后,如果同時存在的話)。

核心方法

  • void afterPropertiesSet():需要實現此方法以定義初始化邏輯。

1.2 用法演示

step1. 定義一個實現?InitializingBean?的 Bean

import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.InitializingBean;public class UserBean implements InitializingBean {private String name;// 屬性注入需要 setter 方法public void setName(String name) {this.name = name;}// 實現 InitializingBean 接口的 afterPropertiesSet 方法@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("InitializingBean 的 afterPropertiesSet() 被調用。");System.out.println("用戶名稱: " + name);}
}

step2. Spring 配置類(Java 配置)

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class AppConfig {@Bean(name = "userBean")public UserBean userBean() {UserBean bean = new UserBean();bean.setName("John Doe"); // 通過 setter 注入屬性return bean;}
}

step3. 啟動 Spring 容器并測試

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class SpringDemo {public static void main(String[] args) {// 創建 Spring 應用上下文ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);// 獲取 Bean(此時已觸發初始化邏輯)UserBean userBean = context.getBean("userBean", UserBean.class);// 輸出結果示例:// InitializingBean 的 afterPropertiesSet() 被調用。// 用戶名稱: John Doe}
}

2. @PostConstruct簡介

2.1 功能簡介

@PostConstruct?是 Java EE/Jakarta EE 中的一個注解(定義于 JSR-250 規范),用于標記一個方法在依賴注入完成后執行初始化操作。它通常與 Spring 框架一起使用,適用于需要在對象初始化時執行特定邏輯的場景。

核心功能

1. 初始化方法:標注的方法會在以下兩個操作完成后被調用:

  • 依賴注入(DI)完成:Spring 容器完成對 Bean 的屬性注入(如?@Autowired@Value?等)。
  • Bean 實例化:Bean 對象被創建后。

2. 執行時機: 是 Bean 生命周期中的一個關鍵步驟,通常在?@Autowired?或其他注入方式完成后執行,但早于?@PreDestroy?注解的銷毀方法。

方法約束

  • 無參數且無返回值:被標注的方法必須是?void?類型且無參數。
@PostConstruct
public void init() { ... } // 正確
  • 不拋出受檢異常:方法不能聲明拋出受檢異常(checked exception),否則會拋出?BeanCreationException
@PostConstruct
public void init() throws IOException { ... } // 錯誤!
  • 實例方法:只能標注在實例方法上,不能用于靜態方法或字段。
  • 唯一性:一個 Bean 中只能有一個?@PostConstruct?方法,否則會引發沖突。

使用場景

  • 資源初始化:例如建立數據庫連接、初始化緩存、加載配置等。
  • 依賴驗證:檢查注入的依賴是否合法。
  • 狀態初始化:設置 Bean 的初始狀態。

注意事項

  • 依賴必須注入完成:在?@PostConstruct?方法中,所有通過?@Autowired?等注入的依賴均已可用。
  • 執行順序: 在以下步驟中觸發:Bean 實例化 → 依賴注入 →?@PostConstruct?方法 →?BeanPostProcessor.postProcessAfterInitialization()

2.2 用法演示

import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;public class MyService {@Autowiredprivate MyRepository repository;@PostConstructpublic void init() {// 在依賴注入完成后執行的初始化邏輯System.out.println("Repository is initialized: " + repository);// 可在此處進行數據庫連接或其他初始化操作}
}

3. InitializingBean?和 @PostConstruct?的對比分析

3.1 對比分析

對比維度@PostConstructInitializingBean
來源Java EE 標準注解(javax.annotation.PostConstruct)。Spring 框架接口(org.springframework.beans.factory.InitializingBean)。
執行時機屬性注入完成后立即執行(在?InitializingBean?的?afterPropertiesSet()?之前)。屬性注入完成后執行(在?@PostConstruct?之后)。
使用方式直接在方法上添加注解,無需實現接口。需要實現接口并重寫?afterPropertiesSet()?方法。
依賴性需要引入?javax.annotation?依賴(Java 9+ 內置,低版本需手動添加)。無需額外依賴(Spring 自帶)。
適用場景簡單的初始化邏輯,且希望代碼不依賴 Spring 特定接口。需要與 Spring 生命周期深度集成(如依賴 Spring 特定功能)或需兼容舊代碼。
侵入性更簡潔,無接口侵入。需實現接口,具有侵入性。

2. 代碼演示:同時使用兩者,驗證執行順序

step1:?定義一個同時使用?@PostConstruct?和?InitializingBean?的 Bean

import javax.annotation.PostConstruct;
import org.springframework.beans.factory.InitializingBean;public class MyBean implements InitializingBean {public MyBean() {System.out.println("構造函數被調用");}@PostConstructpublic void initByPostConstruct() {System.out.println("@PostConstruct 方法執行");}@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("InitializingBean.afterPropertiesSet() 執行");}
}

step2. Spring 配置類(Java 配置)

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
public class AppConfig {@Beanpublic MyBean myBean() {return new MyBean();}
}

step3. 啟動 Spring 容器并觀察輸出

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;public class Main {public static void main(String[] args) {ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);// 輸出順序:// 1. 構造函數被調用// 2. @PostConstruct 方法執行// 3. InitializingBean.afterPropertiesSet() 執行}
}

輸出結果:

構造函數被調用
@PostConstruct 方法執行
InitializingBean.afterPropertiesSet() 執行

關鍵點解釋

  1. 執行順序

    • @PostConstruct?的方法優先于?InitializingBean?的?afterPropertiesSet()?執行。
    • 這是因為 Spring 在初始化 Bean 時,會先處理注解(如?@PostConstruct),再觸發接口定義的回調(如?InitializingBean)。
  2. 構造函數與初始化方法

    • 構造函數在 Bean 實例化時調用(屬性未注入)。
    • 初始化方法(@PostConstruct?和?InitializingBean)在屬性注入完成后調用

3.3 選擇建議

根據場景選擇

  • 推薦使用?@PostConstruct?的場景

    • 需要?簡潔代碼,避免實現接口。
    • 不依賴 Spring 特殊功能,僅需基礎初始化邏輯。
    • 需要在?更早階段?執行初始化(如依賴注入后立即初始化資源)。
  • 推薦使用?InitializingBean?的場景

    • 需要與 Spring 的生命周期深度集成(例如訪問 Spring 上下文)。
    • 項目已有大量使用?InitializingBean?的代碼,無需遷移成本。
    • 需要分階段執行初始化邏輯(如先?@PostConstruct?處理基礎邏輯,再通過?InitializingBean?執行 Spring 特定邏輯)。

總結

  • @PostConstruct?是更現代、簡潔的選擇,且與 Spring 無關(可跨框架使用),適合大多數場景。可視為在 Spring 中用于替代?InitializingBean?接口或 XML 配置的初始化方法,簡化代碼并提高可讀性。
  • InitializingBean?適合需要與 Spring 生命周期深度耦合的情況。但需實現接口,侵入性較強,優先使用@PostConstruct
  • 若同時使用兩者,需注意執行順序并合理規劃邏輯分階段。

3.4 其他替代選擇

SpringBoot啟動后自動執行方法的各種方式-筆記-CSDN博客

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

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

相關文章

《代碼整潔之道》第9章 單元測試 - 筆記

測試驅動開發 (TDD) 是一種編寫整潔代碼的“規程”或“方法論”,而不僅僅是測試技術。 JaCoCo 在運行測試后生成詳細的覆蓋率報告的工具, maven 引用。 測試驅動開發 測試驅動開發(TDD)是什么? TDD 不是說寫完代碼…

openGauss新特性 | DataKit支持PostgreSQL到openGauss的遷移能力

Postgresql-\>openGauss遷移工具debezium-connector-postgres 可獲得性 本特性自openGauss 7.0.0-RC1版本開始引入。 特性簡介 debezium-connector-postgres工具是一個基于Java語言的Postgresql到openGauss的復制工具。該工具提供了初始全量數據及對象(視圖、…

在MySQL Shell里 重啟MySQL 8.4實例

前一段時間看到MySQL官方視頻的Oracle工程師在mysql shell里面重啟mysql實例,感覺這個操作很方便,所以來試試,下面為該工程師的操作截圖 1.MySQL Shell 通過root用戶連上mysql,shutdown mysql實例 [rootmysql8_3 bin]# mysqlshMy…

truffle

文章目錄 truffle目錄結構各文件作用在本地測試合約 truffle 項目來自https://github.com/Dapp-Learning-DAO/Dapp-Learning/blob/main/basic/04-web3js-truffle/README-CN.md Truffle 是基于 Solidity 語言的一套開發框架,它簡化了去中心化應用(Dapp&…

SpringCloud核心組件Eureka菜鳥教程

關于Spring Cloud Eureka的核心概念 Eureka 是 Netflix 開源的一款基于 REST 的服務發現工具,主要用于中間層服務器的云端負載均衡。它通過維護一個服務注冊表來實現服務之間的通信1。在 Spring Cloud 中,Eureka 提供了一個高可用的服務注冊與發現機制&a…

職業教育新形態數字教材的建設與應用:重構教育生態的數字化革命

教育部新時代職業學校名師(名匠)名校長培養計劃專題 四川省第四批職業學校名師(名匠)培養計劃專題 在某職業院校的智能制造課堂上,學生佩戴VR設備,通過數字教材中的虛擬工廠完成設備裝配訓練,系統實時生成操作評分與改進建議。這一場景折射出…

基于Python的攜程國際機票價格抓取與分析

一、項目背景與目標 攜程作為中國領先的在線旅行服務平臺,提供了豐富的機票預訂服務。其國際機票價格受多種因素影響,包括季節、節假日、航班時刻等。通過抓取攜程國際機票價格數據,我們可以進行價格趨勢分析、性價比評估以及旅行規劃建議等…

Windows 圖形顯示驅動開發-初始化WDDM 1.2 和 PnP

(WDDM) 1.2 及更高版本顯示微型端口驅動程序的所有 Windows 顯示驅動程序都必須支持以下行為,以響應即插即用 (PnP) 基礎結構啟動和停止請求。 根據驅動程序返回成功或失敗代碼,或者系統硬件是基于基本輸入/輸出系統 (BIOS) 還是統一可擴展固件接口 (UEF…

【1區SCI】Fusion entropy融合熵,多尺度,復合多尺度、時移多尺度、層次 + 故障識別、診斷-matlab代碼

引言 2024年9月,研究者在數學領域國際頂級SCI期刊《Chaos, Solitons & Fractals》(JCR 1區,中科院1區 Top)上以“Fusion entropy and its spatial post-multiscale version: Methodology and application”為題發表最新科學研…

高并發架構設計之緩存

一、引言 緩存技術作為高并發架構設計的基石之一,通過數據暫存和快速訪問機制,在提升系統性能、降低后端負載方面發揮著不可替代的作用。優秀的緩存設計能夠將系統吞吐量提升數個數量級,將響應時間從秒級降至毫秒級,甚至成為系統…

Unity AI-使用Ollama本地大語言模型運行框架運行本地Deepseek等模型實現聊天對話(一)

一、Ollama介紹 官方網頁:Ollama官方網址 中文文檔參考:Ollama中文文檔 相關教程:Ollama教程 Ollama 是一個開源的工具,旨在簡化大型語言模型(LLM)在本地計算機上的運行和管理。它允許用戶無需復雜的配置…

Docker Python 鏡像使用指南

1. 使用 Python 鏡像創建容器 docker run -itd -v /data:/data python:latest 作用:創建一個基于 python:latest 鏡像的容器,并后臺運行。 參數說明: -itd:交互式后臺運行(-i 交互模式,-t 分配偽終端&…

matlab中Simscape的調用-入門

Simscape 是由 MathWorks 公司開發的一款基于物理建模的仿真工具,它建立在 MATLAB/Simulink 平臺之上,專門用于建模和仿真多領域物理系統。 主要特點 多領域建模:Simscape 提供了豐富的物理元件庫,涵蓋了機械、電氣、液壓、氣動…

Flowable7.x學習筆記(十三)查看部署流程圖

前言 Flowable 的流程圖是 Flowable Modeler 或 Process Editor 中,使用拖拽和屬性面板基于 BPMN 2.0 元素(如任務、網關、事件、序列流等)渲染出的業務流程圖形界面?。 一、將圖形導出可查看的作用 ① 可視化建模 幫助業務分析師和開發者…

Bootstrap 模態框

Bootstrap 模態框 Bootstrap 模態框(Modal)是 Bootstrap 框架中的一個組件,它允許你在一個頁面中創建一個模態對話框,用于顯示內容、表單、圖像或其他信息。模態框通常覆蓋在當前頁面上,提供了一種不離開當前頁面的交…

python-69-基于graphviz可視化軟件生成流程圖

文章目錄 1 Graphviz可視化軟件1.1 graphviz簡介1.2 安裝部署2 基于python示例應用2.1 基本示例2.2 解決中文顯示亂碼2.3 顯示多個輸出邊2.4 顯示輸出引腳名稱2.5 從左至右顯示布局2.6 設置節點為方形3 參考附錄1 Graphviz可視化軟件 1.1 graphviz簡介 Graphviz(Graph Visua…

AJAX 介紹

一、什么是AJAX ? AJAX 是 異步的 JavaScript 和 XML(Asynchronous JavaScript And XML) 的縮寫,是一種實現瀏覽器與服務器進行數據通信的技術。其核心是通過 XMLHttpRequest 對象在不重新刷新頁面的前提下,與服務器交換數據并更…

新ubuntu物理機開啟ipv6讓外網訪問

Ubuntu 物理機 SSH 遠程連接與 IPv6 外網訪問測試指南 1. 通過 SSH 遠程連接 Ubuntu 物理機 1.1 安裝 SSH 服務 sudo apt update sudo apt install openssh-server1.2 檢查 SSH 服務狀態 sudo systemctl status ssh確認出現 active (running)。 1.3 獲取物理機 IP 地址 i…

linux系統上使用nginx訪問php文件返回File not found錯誤處理方案

linux系統上使用nginx訪問php文件返回File not found錯誤處理方案 第一種情況第二種情況 第一種情況 可以在你的location php 里面添加當文件不存在時返回404而不是交給php-fpm進行處理 location ~ \.php$ { ... #文件不存在轉404 try_files $uri 404; ... }然后&#xff0c…

基于 SpringBoot 與 Redis 的緩存預熱案例

文章目錄 “緩存預熱” 是什么?項目環境搭建創建數據訪問層預熱數據到 Redis 中創建緩存服務類測試緩存預熱 “緩存預熱” 是什么? 緩存預熱是一種優化策略,在系統啟動或者流量高峰來臨之前,將一些經常訪問的數據提前加載到緩存中…