最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring中InitializingBean接口和@PostConstruct注解的使用詳解

 更新時(shí)間:2025年04月29日 10:09:40   作者:饕餮爭(zhēng)鋒  
InitializingBean 是 Spring 框架中的一個(gè)接口,用在 Bean 初始化后執(zhí)行自定義邏輯,@PostConstruct 是 Java EE/Jakarta EE 中的一個(gè)注解用于標(biāo)記一個(gè)方法在依賴注入完成后執(zhí)行初始化操作,下面我們就來(lái)深入了解下二者的使用吧

1. InitializingBean 簡(jiǎn)介

1.1 功能簡(jiǎn)介

InitializingBean 是 Spring 框架中的一個(gè)接口,用在 Bean 初始化后執(zhí)行自定義邏輯。它提供了 afterPropertiesSet() 方法,該方法在以下時(shí)機(jī)被 Spring 容器自動(dòng)調(diào)用:

  • 屬性注入完成后(即所有通過(guò) setter 方法或構(gòu)造函數(shù)注入的屬性已設(shè)置完畢)。
  • Bean 初始化階段的最后一步(在調(diào)用 @PostConstruct 注解的方法之后,如果同時(shí)存在的話)。

核心方法

void afterPropertiesSet():需要實(shí)現(xiàn)此方法以定義初始化邏輯。

1.2 用法演示

step1. 定義一個(gè)實(shí)現(xiàn) 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;
    }
 
    // 實(shí)現(xiàn) InitializingBean 接口的 afterPropertiesSet 方法
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("InitializingBean 的 afterPropertiesSet() 被調(diào)用。");
        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"); // 通過(guò) setter 注入屬性
        return bean;
    }
}

step3. 啟動(dòng) Spring 容器并測(cè)試

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

2. @PostConstruct簡(jiǎn)介

2.1 功能簡(jiǎn)介

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

核心功能

1. 初始化方法:標(biāo)注的方法會(huì)在以下兩個(gè)操作完成后被調(diào)用:

  • 依賴注入(DI)完成:Spring 容器完成對(duì) Bean 的屬性注入(如 @Autowired、@Value 等)。
  • Bean 實(shí)例化:Bean 對(duì)象被創(chuàng)建后。

2. 執(zhí)行時(shí)機(jī): 是 Bean 生命周期中的一個(gè)關(guān)鍵步驟,通常在 @Autowired 或其他注入方式完成后執(zhí)行,但早于 @PreDestroy 注解的銷毀方法。

方法約束

無(wú)參數(shù)且無(wú)返回值:被標(biāo)注的方法必須是 void 類型且無(wú)參數(shù)。

@PostConstruct
public void init() { ... } // 正確

不拋出受檢異常:方法不能聲明拋出受檢異常(checked exception),否則會(huì)拋出 BeanCreationException。

@PostConstruct
public void init() throws IOException { ... } // 錯(cuò)誤!

實(shí)例方法:只能標(biāo)注在實(shí)例方法上,不能用于靜態(tài)方法或字段。

唯一性:一個(gè) Bean 中只能有一個(gè) @PostConstruct 方法,否則會(huì)引發(fā)沖突。

使用場(chǎng)景

  • 資源初始化:例如建立數(shù)據(jù)庫(kù)連接、初始化緩存、加載配置等。
  • 依賴驗(yàn)證:檢查注入的依賴是否合法。
  • 狀態(tài)初始化:設(shè)置 Bean 的初始狀態(tài)。

注意事項(xiàng)

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

2.2 用法演示

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

3. InitializingBean 和 @PostConstruct 的對(duì)比分析

3.1 對(duì)比分析

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

3.2 代碼演示

同時(shí)使用兩者,驗(yàn)證執(zhí)行順序

step1: 定義一個(gè)同時(shí)使用 @PostConstruct 和 InitializingBean 的 Bean

import javax.annotation.PostConstruct;
import org.springframework.beans.factory.InitializingBean;
 
public class MyBean implements InitializingBean {
 
    public MyBean() {
        System.out.println("構(gòu)造函數(shù)被調(diào)用");
    }
 
    @PostConstruct
    public void initByPostConstruct() {
        System.out.println("@PostConstruct 方法執(zhí)行");
    }
 
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("InitializingBean.afterPropertiesSet() 執(zhí)行");
    }
}

step2. Spring 配置類(Java 配置)

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

step3. 啟動(dòng) 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. 構(gòu)造函數(shù)被調(diào)用
        // 2. @PostConstruct 方法執(zhí)行
        // 3. InitializingBean.afterPropertiesSet() 執(zhí)行
    }
}

輸出結(jié)果:

構(gòu)造函數(shù)被調(diào)用
@PostConstruct 方法執(zhí)行
InitializingBean.afterPropertiesSet() 執(zhí)行

關(guān)鍵點(diǎn)解釋

1.執(zhí)行順序:

  • @PostConstruct 的方法優(yōu)先于 InitializingBean 的 afterPropertiesSet() 執(zhí)行。
  • 這是因?yàn)?Spring 在初始化 Bean 時(shí),會(huì)先處理注解(如 @PostConstruct),再觸發(fā)接口定義的回調(diào)(如 InitializingBean)。

2.構(gòu)造函數(shù)與初始化方法:

  • 構(gòu)造函數(shù)在 Bean 實(shí)例化時(shí)調(diào)用(屬性未注入)。
  • 初始化方法(@PostConstruct 和 InitializingBean)在屬性注入完成后調(diào)用

3.3 選擇建議

根據(jù)場(chǎng)景選擇

推薦使用 @PostConstruct 的場(chǎng)景:

  • 需要 簡(jiǎn)潔代碼,避免實(shí)現(xiàn)接口。
  • 不依賴 Spring 特殊功能,僅需基礎(chǔ)初始化邏輯。
  • 需要在 更早階段 執(zhí)行初始化(如依賴注入后立即初始化資源)。

推薦使用 InitializingBean 的場(chǎng)景:

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

總結(jié)

@PostConstruct 是更現(xiàn)代、簡(jiǎn)潔的選擇,且與 Spring 無(wú)關(guān)(可跨框架使用),適合大多數(shù)場(chǎng)景??梢暈樵?Spring 中用于替代 InitializingBean 接口或 XML 配置的初始化方法,簡(jiǎn)化代碼并提高可讀性。

InitializingBean 適合需要與 Spring 生命周期深度耦合的情況。但需實(shí)現(xiàn)接口,侵入性較強(qiáng),優(yōu)先使用@PostConstruct。

若同時(shí)使用兩者,需注意執(zhí)行順序并合理規(guī)劃邏輯分階段。

以上就是Spring中InitializingBean接口和@PostConstruct注解的使用詳解的詳細(xì)內(nèi)容,更多關(guān)于Spring InitializingBean @PostConstruct的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • MAC?在類路徑或引導(dǎo)類路徑中找不到程序包?java.lang問(wèn)題

    MAC?在類路徑或引導(dǎo)類路徑中找不到程序包?java.lang問(wèn)題

    這篇文章主要介紹了MAC?在類路徑或引導(dǎo)類路徑中找不到程序包?java.lang問(wèn)題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • Java資源緩存 之 LruCache

    Java資源緩存 之 LruCache

    LruCache (此類在android-support-v4的包中提供) 這個(gè)類非常適合用來(lái)緩存圖片,它的主要算法原理是把最近使用的對(duì)象用強(qiáng)引用存儲(chǔ)在 LinkedHashMap 中,并且把最近最少使用的對(duì)象在緩存值達(dá)到預(yù)設(shè)定值之前從內(nèi)存中移除。
    2016-08-08
  • Java中的對(duì)象和引用詳解

    Java中的對(duì)象和引用詳解

    這篇文章主要介紹了Java中的對(duì)象和引用詳解的相關(guān)資料,需要的朋友可以參考下
    2017-05-05
  • java 圖片驗(yàn)證碼的實(shí)現(xiàn)代碼

    java 圖片驗(yàn)證碼的實(shí)現(xiàn)代碼

    java 圖片驗(yàn)證碼的實(shí)現(xiàn)代碼,需要的朋友可以參考一下
    2013-05-05
  • 修改maven本地倉(cāng)庫(kù)路徑的方法

    修改maven本地倉(cāng)庫(kù)路徑的方法

    本篇文章主要介紹了修改maven本地倉(cāng)庫(kù)路徑的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-12-12
  • springboot后端接收前端傳數(shù)組參數(shù)三種方法

    springboot后端接收前端傳數(shù)組參數(shù)三種方法

    這篇文章主要給大家介紹了關(guān)于springboot后端接收前端傳數(shù)組參數(shù)三種方法,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2023-07-07
  • Java使用kafka發(fā)送和生產(chǎn)消息的示例

    Java使用kafka發(fā)送和生產(chǎn)消息的示例

    本篇文章主要介紹了Java使用kafka發(fā)送和生產(chǎn)消息的示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-04-04
  • pagehelper分頁(yè)工具類的封裝

    pagehelper分頁(yè)工具類的封裝

    這篇文章主要為大家詳細(xì)介紹了pagehelper分頁(yè)工具類的封裝,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • Java Process.waitFor()方法詳解

    Java Process.waitFor()方法詳解

    這篇文章主要介紹了Java Process.waitFor()方法詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • Mybatis-Plus3.2.0 MetaObjectHandler 無(wú)法進(jìn)行公共字段全局填充

    Mybatis-Plus3.2.0 MetaObjectHandler 無(wú)法進(jìn)行公共字段全局填充

    這篇文章主要介紹了Mybatis-Plus3.2.0 MetaObjectHandler 無(wú)法進(jìn)行公共字段全局填充,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11

最新評(píng)論

珲春市| 石阡县| 麟游县| 巩留县| 育儿| 马龙县| 云梦县| 洱源县| 清远市| 栾川县| 灵石县| 伊川县| 鄱阳县| 宁河县| 安远县| 张家口市| 峨眉山市| 海晏县| 龙井市| 偃师市| 柏乡县| 周口市| 大荔县| 兰坪| 新昌县| 昆明市| 富裕县| 海南省| 德江县| 铜梁县| 栖霞市| 五常市| 贵德县| 鹤山市| 随州市| 京山县| 博野县| 晋江市| 昌邑市| 乌拉特后旗| 邢台县|