欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring干預(yù)Bean的生命周期的方法詳解

 更新時(shí)間:2025年07月08日 08:27:26   作者:冰糖心書(shū)房  
Spring 提供了多種機(jī)制讓我們能夠在 Bean 生命周期的不同節(jié)點(diǎn)“插入”自己的邏輯,這些機(jī)制可以分為兩大類(lèi):針對(duì)單個(gè) Bean 的干預(yù)和針對(duì)所有/多個(gè) Bean 的全局干預(yù),本文將通過(guò)代碼示例給大家詳細(xì)的介紹一下,需要的朋友可以參考下

Spring 提供了多種機(jī)制讓我們能夠在 Bean 生命周期的不同節(jié)點(diǎn)“插入”自己的邏輯,這些機(jī)制可以分為兩大類(lèi):針對(duì)單個(gè) Bean 的干預(yù)針對(duì)所有/多個(gè) Bean 的全局干預(yù)。

一、 針對(duì)單個(gè) Bean 的干預(yù)(最常用)

這些方法讓你為一個(gè)特定的 Bean 類(lèi)定義其初始化和銷(xiāo)毀邏輯。

1. 使用 JSR-250 注解(推薦方式)

這是現(xiàn)在最優(yōu)雅、也是 Spring 官方推薦的方式。它使用 Java 的標(biāo)準(zhǔn)注解,與 Spring 框架解耦。

  • @PostConstruct:在依賴注入完成之后,執(zhí)行任何自定義的初始化邏輯。可以把它看作是 Bean 的“構(gòu)造函數(shù)完成后的補(bǔ)充構(gòu)造函數(shù)”。
  • @PreDestroy:在容器銷(xiāo)毀 Bean 之前,執(zhí)行清理工作。

示例:

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

@Service
public class DataProcessor {

    @Autowired
    private DataSource dataSource; // 依賴會(huì)被先注入

    private Connection connection;

    public DataProcessor() {
        System.out.println("1. 調(diào)用構(gòu)造函數(shù): dataSource is null? " + (dataSource == null));
    }

    @PostConstruct
    public void openConnection() {
        System.out.println("3. 執(zhí)行 @PostConstruct: dataSource is null? " + (dataSource == null));
        System.out.println("正在打開(kāi)數(shù)據(jù)庫(kù)連接...");
        // 此時(shí) dataSource 已經(jīng)被注入,可以安全使用
        // this.connection = dataSource.getConnection(); 
    }

    public void process() {
        System.out.println("正在處理數(shù)據(jù)...");
    }

    @PreDestroy
    public void closeConnection() {
        System.out.println("執(zhí)行 @PreDestroy: 正在關(guān)閉數(shù)據(jù)庫(kù)連接...");
        // if (this.connection != null) this.connection.close();
    }
}

優(yōu)點(diǎn):代碼簡(jiǎn)潔,與 Spring 解耦,符合 Java EE 規(guī)范。

2. 實(shí)現(xiàn) Spring 的特定接口

這是 Spring 早期提供的方式,需要你的 Bean 類(lèi)實(shí)現(xiàn) Spring 框架的接口。

  • InitializingBean:實(shí)現(xiàn)它的 afterPropertiesSet() 方法,效果同 @PostConstruct。
  • DisposableBean:實(shí)現(xiàn)它的 destroy() 方法,效果同 @PreDestroy。

示例:

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.DisposableBean;

@Component
public class LegacyService implements InitializingBean, DisposableBean {

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("執(zhí)行 InitializingBean.afterPropertiesSet()");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("執(zhí)行 DisposableBean.destroy()");
    }
}

缺點(diǎn):代碼與 Spring 框架產(chǎn)生了強(qiáng)耦合,不推薦在新代碼中使用。

3. 在配置中指定 init-method 和 destroy-method

這種方式完全將生命周期邏輯的調(diào)用與 Bean 類(lèi)本身解耦。適用于你無(wú)法修改其源代碼的第三方庫(kù) Bean。

XML 配置:

<bean id="myService" class="com.example.MyService" 
      init-method="customInit" 
      destroy-method="customCleanup"/>

Java 配置:

@Configuration
public class AppConfig {
    @Bean(initMethod = "customInit", destroyMethod = "customCleanup")
    public MyService myService() {
        return new MyService();
    }
}

優(yōu)點(diǎn):對(duì)類(lèi)代碼無(wú)侵入。

三者執(zhí)行順序@PostConstruct -> InitializingBean.afterPropertiesSet() -> init-method。

二、 針對(duì)所有/多個(gè) Bean 的全局干預(yù)(高級(jí)/框架級(jí))

這些機(jī)制是 Spring 框架的強(qiáng)大武器,允許你對(duì)容器中所有(或部分)Bean 的生命周期進(jìn)行統(tǒng)一的、批量的處理。

1. BeanPostProcessor(Bean 后置處理器)

這是最重要、最強(qiáng)大的全局干預(yù)接口。它像一個(gè)“質(zhì)檢員”,容器中每一個(gè) Bean 在初始化前后都會(huì)經(jīng)過(guò)它進(jìn)行“檢查”和“加工”。

它有兩個(gè)核心方法:

  • postProcessBeforeInitialization(Object bean, String beanName):在任何 Bean 的初始化方法(如 @PostConstruct調(diào)用前執(zhí)行。
  • postProcessAfterInitialization(Object bean, String beanName):在任何 Bean 的初始化方法調(diào)用后執(zhí)行。

Spring 的 AOP(如 @Transactional)就是通過(guò) BeanPostProcessor 實(shí)現(xiàn)的。它在 postProcessAfterInitialization 階段檢查 Bean,如果發(fā)現(xiàn)需要代理,就返回一個(gè)代理對(duì)象來(lái)替換原始的 Bean 實(shí)例。

示例: 創(chuàng)建一個(gè)打印所有 Bean 初始化信息的后置處理器。

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("質(zhì)檢員[Before]: 正在檢查 " + beanName);
        return bean; // 必須返回 bean,否則后續(xù)流程拿不到對(duì)象
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("質(zhì)檢員[After]: " + beanName + " 已完成初始化。");
        // 這里可以返回原始 bean,也可以返回一個(gè)包裝后的代理 bean
        return bean;
    }
}

2. Aware 系列接口

Aware 接口的作用是讓 Bean 能夠“感知”并獲取到它所在的容器環(huán)境資源。這發(fā)生在依賴注入之后,自定義初始化方法之前

  • BeanNameAware:讓 Bean 知道它在容器中的 ID。
  • BeanFactoryAware:讓 Bean 獲取到創(chuàng)建它的 BeanFactory,從而可以編程方式地獲取其他 Bean。
  • ApplicationContextAware:功能同上,但獲取的是功能更強(qiáng)大的 ApplicationContext。

示例:

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class AwareService implements ApplicationContextAware {

    private ApplicationContext context;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        System.out.println("AwareService 感知到了 ApplicationContext");
        this.context = applicationContext;
    }
    
    public void doSomething() {
        // 可以通過(guò) context 手動(dòng)獲取其他 bean
        DataProcessor processor = context.getBean(DataProcessor.class);
        processor.process();
    }
}

注意:過(guò)度使用 Aware 接口會(huì)增加代碼與 Spring 容器的耦合度,應(yīng)謹(jǐn)慎使用。

總結(jié)

干預(yù)方式作用階段影響范圍推薦度/適用場(chǎng)景
@PostConstruct / @PreDestroy初始化后 / 銷(xiāo)毀前單個(gè) Bean強(qiáng)烈推薦,代碼清晰,與框架解耦。
InitializingBean / DisposableBean初始化后 / 銷(xiāo)毀前單個(gè) Bean不推薦,與 Spring 強(qiáng)耦合,用于兼容老代碼。
init-method / destroy-method初始化后 / 銷(xiāo)毀前單個(gè) Bean推薦,用于無(wú)法修改源碼的第三方 Bean。
BeanPostProcessor初始化前后所有 Bean高級(jí)/框架級(jí)。用于實(shí)現(xiàn) AOP、自定義注解處理等全局邏輯。
Aware 接口初始化前單個(gè) Bean謹(jǐn)慎使用。當(dāng) Bean 需要主動(dòng)與容器交互時(shí)使用。

簡(jiǎn)單來(lái)說(shuō),作為應(yīng)用開(kāi)發(fā)者,你的首選和絕大多數(shù)情況下的選擇應(yīng)該是 @PostConstruct@PreDestroy 如果你需要開(kāi)發(fā)框架級(jí)別的功能,那么 BeanPostProcessor 則是你的核武器。

以上就是Spring干預(yù)Bean的生命周期的方法詳解的詳細(xì)內(nèi)容,更多關(guān)于Spring干預(yù)Bean生命周期的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Java畢業(yè)設(shè)計(jì)實(shí)戰(zhàn)之工作管理系統(tǒng)的實(shí)現(xiàn)

    Java畢業(yè)設(shè)計(jì)實(shí)戰(zhàn)之工作管理系統(tǒng)的實(shí)現(xiàn)

    這是一個(gè)使用了java+SSM+Jsp+Mysql開(kāi)發(fā)的工作干活管理系統(tǒng),是一個(gè)畢業(yè)設(shè)計(jì)的實(shí)戰(zhàn)練習(xí),具有管理系統(tǒng)該有的所有功能,感興趣的朋友快來(lái)看看吧
    2022-02-02
  • intellij idea如何配置網(wǎng)絡(luò)代理

    intellij idea如何配置網(wǎng)絡(luò)代理

    intellij idea所在的這臺(tái)電腦本身上不了網(wǎng),要通過(guò)代理上網(wǎng),那么intellij idea怎么設(shè)置代理上網(wǎng)呢?今天通過(guò)本文給大家分享intellij idea如何配置網(wǎng)絡(luò)代理,感興趣的朋友一起看看吧
    2023-10-10
  • SpringBoot實(shí)現(xiàn)聯(lián)表查詢的代碼詳解

    SpringBoot實(shí)現(xiàn)聯(lián)表查詢的代碼詳解

    這篇文章主要介紹了SpringBoot中如何實(shí)現(xiàn)聯(lián)表查詢,文中通過(guò)代碼示例和圖文結(jié)合的方式講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-05-05
  • IDEA中的JFormDesigner使用小結(jié)

    IDEA中的JFormDesigner使用小結(jié)

    JFormDesigner是一款用于設(shè)計(jì)和創(chuàng)建圖形用戶界面的插件,本文主要介紹了IDEA中的JFormDesigner使用小結(jié),具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-01-01
  • java微信掃描公眾號(hào)二維碼實(shí)現(xiàn)登陸功能

    java微信掃描公眾號(hào)二維碼實(shí)現(xiàn)登陸功能

    這篇文章主要為大家詳細(xì)介紹了PHP微信掃描公眾號(hào)二維碼實(shí)現(xiàn)登陸功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • 淺析Hadoop完全分布式集群搭建問(wèn)題

    淺析Hadoop完全分布式集群搭建問(wèn)題

    Hadoop是一個(gè)由Apache基金會(huì)所開(kāi)發(fā)的分布式系統(tǒng)基礎(chǔ)架構(gòu)。本文重點(diǎn)給大家介紹Hadoop完全分布式集群搭建問(wèn)題,感興趣的朋友跟隨小編一起看看吧
    2021-11-11
  • springboot實(shí)現(xiàn)jar運(yùn)行復(fù)制resources文件到指定的目錄(思路詳解)

    springboot實(shí)現(xiàn)jar運(yùn)行復(fù)制resources文件到指定的目錄(思路詳解)

    這篇文章主要介紹了springboot實(shí)現(xiàn)jar運(yùn)行復(fù)制resources文件到指定的目錄,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-04-04
  • Mybatis中的延遲加載詳細(xì)解讀

    Mybatis中的延遲加載詳細(xì)解讀

    這篇文章主要介紹了Mybatis中的延遲加載詳細(xì)解讀,Mybatis中延遲加載又稱為懶加載,是指在進(jìn)行關(guān)聯(lián)查詢時(shí),按照設(shè)置延遲規(guī)則推遲對(duì)關(guān)聯(lián)對(duì)象的select查詢,延遲加載可以有效的減少數(shù)據(jù)庫(kù)的壓力,需要的朋友可以參考下
    2023-10-10
  • Java8新特性之Lambda表達(dá)式的使用

    Java8新特性之Lambda表達(dá)式的使用

    這篇文章主要介紹了Java8新特性之Lambda表達(dá)式的使用,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-04-04
  • 解決springboot 2.x集成log4j2調(diào)試日志無(wú)法關(guān)閉的問(wèn)題

    解決springboot 2.x集成log4j2調(diào)試日志無(wú)法關(guān)閉的問(wèn)題

    這篇文章主要介紹了解決springboot 2.x集成log4j2調(diào)試日志無(wú)法關(guān)閉的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07

最新評(píng)論