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

深度解析Spring Bean生命周期以及LomBok插件

 更新時(shí)間:2026年01月13日 14:45:51   作者:柒.梧.  
本文詳細(xì)介紹了Spring框架中Bean的生命周期,包括核心差異、完整階段拆解、回調(diào)方法實(shí)現(xiàn)方式及優(yōu)先級(jí),Bean后置處理器的關(guān)鍵知識(shí)點(diǎn),并通過實(shí)戰(zhàn)測(cè)試驗(yàn)證了整個(gè)生命周期流程,感興趣的朋友跟隨小編一起看看吧

在Spring框架中,Bean的生命周期是核心知識(shí)點(diǎn)之一,也是面試中的高頻考點(diǎn)。相比于傳統(tǒng)Java應(yīng)用中Bean簡(jiǎn)單的“實(shí)例化-使用-垃圾回收”流程,Spring IOC容器對(duì)Bean的生命周期提供了完整的管理能力,支持在特定階段執(zhí)行定制化任務(wù)。本文將從核心差異入手,層層拆解Spring Bean的生命周期階段,結(jié)合具體代碼案例詳解生命周期回調(diào)方法的實(shí)現(xiàn)方式,并補(bǔ)充Bean后置處理器的關(guān)鍵知識(shí)點(diǎn),幫助大家徹底掌握這一核心內(nèi)容。

一、傳統(tǒng)Java vs Spring:Bean生命周期核心差異

在傳統(tǒng)Java應(yīng)用中,Bean的生命周期邏輯非常簡(jiǎn)單,完全由JVM主導(dǎo):

  • 實(shí)例化:通過new關(guān)鍵字調(diào)用構(gòu)造器創(chuàng)建Bean實(shí)例;
  • 使用:實(shí)例創(chuàng)建完成后直接調(diào)用方法即可使用;
  • 銷毀:當(dāng)Bean長(zhǎng)期不被使用,失去引用后,JVM自動(dòng)執(zhí)行垃圾回收。

而Spring中的Bean生命周期則由IOC容器全程管理,流程更復(fù)雜,但靈活性更高——Spring允許我們?cè)贐ean生命周期的關(guān)鍵節(jié)點(diǎn)插入自定義邏輯,實(shí)現(xiàn)對(duì)Bean的精細(xì)化管控。這種管控能力也是Spring框架核心優(yōu)勢(shì)之一。

二、Spring Bean生命周期完整階段拆解

Spring Bean的生命周期從IOC容器初始化開始,到IOC容器關(guān)閉結(jié)束,整個(gè)流程可拆解為8個(gè)核心階段,各階段按順序依次執(zhí)行:

  • Bean對(duì)象創(chuàng)建:IOC容器初始化時(shí),通過Java反射機(jī)制調(diào)用Bean的無(wú)參構(gòu)造器,生成Bean的實(shí)例對(duì)象;
  • Bean對(duì)象屬性注入:同樣通過反射機(jī)制,調(diào)用Bean的setter方法,將配置文件或注解中定義的屬性值注入到Bean實(shí)例中;
  • Bean初始化前操作:由Bean后置處理器(BeanPostProcessor)的postProcessBeforeInitialization方法負(fù)責(zé)執(zhí)行,屬于全局定制化操作;
  • Bean對(duì)象初始化:需在Bean配置時(shí)指定初始化方法(如接口實(shí)現(xiàn)、XML配置、注解方式),容器會(huì)調(diào)用該方法執(zhí)行初始化邏輯;
  • Bean初始化后操作:由Bean后置處理器的postProcessAfterInitialization方法負(fù)責(zé)執(zhí)行,同樣是全局生效的定制化操作;
  • Bean對(duì)象就緒可用:經(jīng)過以上階段后,Bean實(shí)例已完全初始化完成,可通過IOC容器的getBean()方法獲取并使用;
  • Bean對(duì)象銷毀:需在Bean配置時(shí)指定銷毀方法,當(dāng)IOC容器關(guān)閉時(shí),容器會(huì)調(diào)用該方法執(zhí)行銷毀邏輯(如資源釋放);
  • IOC容器關(guān)閉:容器完成所有Bean的銷毀后,自身關(guān)閉,生命周期結(jié)束。

提示:核心記憶點(diǎn)——“創(chuàng)建-注入-初始化前后-就緒-銷毀-容器關(guān)閉”,其中初始化前后的操作由后置處理器主導(dǎo),初始化和銷毀需自定義方法并配置。

三、Bean生命周期回調(diào)方法:3種實(shí)現(xiàn)方式與優(yōu)先級(jí)

Spring允許我們通過“生命周期回調(diào)方法”在Bean的初始化(第4階段)和銷毀(第7階段)時(shí)刻執(zhí)行自定義邏輯(如資源加載、連接關(guān)閉等)。共有3種實(shí)現(xiàn)方式,且存在明確的優(yōu)先級(jí)順序。

核心優(yōu)先級(jí)規(guī)則:注解 > 接口實(shí)現(xiàn) > XML配置

方式一:接口實(shí)現(xiàn)(InitializingBean + DisposableBean)

通過讓Bean類實(shí)現(xiàn)Spring提供的InitializingBean(初始化回調(diào))和DisposableBean(銷毀回調(diào))接口,重寫接口中的方法即可實(shí)現(xiàn)定制邏輯。

1. 代碼實(shí)現(xiàn)

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
public class Dog implements InitializingBean, DisposableBean {
    private String name;
    private String owner;
    private int age;
    // 1. 無(wú)參構(gòu)造器:階段1(Bean對(duì)象創(chuàng)建)執(zhí)行
    public Dog() {
        System.out.println("Dog對(duì)象被創(chuàng)建...");
    }
    // Setter方法:階段2(屬性注入)執(zhí)行
    public void setName(String name) {
        System.out.println("調(diào)用setName方法....");
        this.name = name;
    }
    public void setOwner(String owner) {
        System.out.println("調(diào)用setOwner方法....");
        this.owner = owner;
    }
    public void setAge(int age) {
        System.out.println("調(diào)用setAge方法....");
        this.age = age;
    }
    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                ", owner='" + owner + '\'' +
                ", age=" + age +
                '}';
    }
    // 2. 初始化回調(diào):實(shí)現(xiàn)InitializingBean接口,階段4執(zhí)行
    // 該方法在屬性注入完成后調(diào)用
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("調(diào)用接口:InitializingBean,方法:afterPropertiesSet,無(wú)參數(shù)");
    }
    // 3. 銷毀回調(diào):實(shí)現(xiàn)DisposableBean接口,階段7執(zhí)行
    // 該方法在容器關(guān)閉時(shí)調(diào)用
    @Override
    public void destroy() throws Exception {
        System.out.println("調(diào)用接口:DisposableBean,方法:destroy,無(wú)參數(shù)");
    }
}

2. 注意事項(xiàng)

這種方式的缺點(diǎn)是耦合性高——Bean類直接依賴Spring框架的接口,導(dǎo)致代碼與Spring框架緊耦合,不利于后續(xù)的擴(kuò)展和遷移。因此,在實(shí)際開發(fā)中,除非有特殊需求,否則不建議優(yōu)先使用。

方式二:XML配置(init-method + destroy-method)

通過Spring的XML配置文件,在<bean>標(biāo)簽中通過init-method屬性指定初始化方法名,通過destroy-method屬性指定銷毀方法名,無(wú)需Bean類實(shí)現(xiàn)任何接口,降低了耦合性。

1. 代碼實(shí)現(xiàn)

首先,在Dog類中定義自定義的初始化和銷毀方法(方法名可任意,無(wú)參數(shù)):

public class Dog {
    private String name;
    private String owner;
    private int age;
    public Dog() {
        System.out.println("Dog對(duì)象被創(chuàng)建...");
    }
    // Setter方法省略...
    // 自定義初始化方法:對(duì)應(yīng)init-method
    public void initDog() {
        System.out.println("XML配置:執(zhí)行自定義初始化方法 initDog");
    }
    // 自定義銷毀方法:對(duì)應(yīng)destroy-method
    public void destroyDog() {
        System.out.println("XML配置:執(zhí)行自定義銷毀方法 destroyDog");
    }
    // toString方法省略...
}

然后,在XML配置文件(applicationContext.xml)中配置屬性:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!-- 配置Dog Bean,指定初始化和銷毀方法 -->
    <bean id="dog" 
          class="com.qcby.Dog" 
          p:name="admin" 
          p:owner="aaa" 
          p:age="18" 
          init-method="initDog" 
          destroy-method="destroyDog"/>
</beans>

2. 核心優(yōu)勢(shì)

完全解耦:Bean類是純Java類,不依賴任何Spring接口或注解,通用性更強(qiáng),便于維護(hù)和遷移。適合基于XML配置的傳統(tǒng)Spring項(xiàng)目。

方式三:注解實(shí)現(xiàn)(@PostConstruct + @PreDestroy)

通過JDK提供的@PostConstruct(初始化回調(diào))和@PreDestroy(銷毀回調(diào))注解,直接標(biāo)注在Bean類的方法上,實(shí)現(xiàn)定制邏輯。這是目前開發(fā)中最常用的方式,簡(jiǎn)潔高效且耦合性低。

1. 代碼實(shí)現(xiàn)

首先,需要引入lombok依賴(若未引入,也可直接使用注解,不影響功能):

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.12</version>
    <scope>provided</scope>
</dependency>

然后,在Dog類中使用注解標(biāo)注方法:

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
public class Dog {
    private String name;
    private String owner;
    private int age;
    public Dog() {
        System.out.println("Dog對(duì)象被創(chuàng)建...");
    }
    // Setter方法省略...
    // 初始化回調(diào):@PostConstruct,階段4執(zhí)行
    @PostConstruct
    public void initByAnnotation() {
        System.out.println("注解方式:執(zhí)行@PostConstruct標(biāo)注的初始化方法");
    }
    // 銷毀回調(diào):@PreDestroy,階段7執(zhí)行
    @PreDestroy
    public void destroyByAnnotation() {
        System.out.println("注解方式:執(zhí)行@PreDestroy標(biāo)注的銷毀方法");
    }
    // toString方法省略...
}

最后,在XML或注解配置中掃描該Bean(確保IOC容器能識(shí)別):

<!-- XML配置掃描包 -->
<context:component-scan base-package="com.xxx"/>

2. 核心優(yōu)勢(shì)

1. 簡(jiǎn)潔高效:無(wú)需實(shí)現(xiàn)接口,無(wú)需XML配置,直接通過注解標(biāo)注即可;2. 耦合性低:注解是JDK原生提供(非Spring專屬),Bean類通用性強(qiáng);3. 優(yōu)先級(jí)最高:當(dāng)多種方式同時(shí)存在時(shí),注解標(biāo)注的方法會(huì)優(yōu)先執(zhí)行。

四、關(guān)鍵擴(kuò)展:Bean后置處理器(BeanPostProcessor)

Bean后置處理器是Spring提供的一種全局?jǐn)U展機(jī)制,它不針對(duì)某個(gè)特定的Bean,而是對(duì)IOC容器中所有的Bean生效,主要作用于Bean初始化的前后兩個(gè)階段(對(duì)應(yīng)生命周期的第3和第5階段)。

1. 核心作用

  • 初始化前(postProcessBeforeInitialization):對(duì)初始化前的Bean實(shí)例進(jìn)行增強(qiáng)或修改;
  • 初始化后(postProcessAfterInitialization):對(duì)初始化后的Bean實(shí)例進(jìn)行增強(qiáng)或修改(如AOP的動(dòng)態(tài)代理就是基于此實(shí)現(xiàn))。

2. 實(shí)現(xiàn)步驟

步驟1:創(chuàng)建后置處理器類

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
// 自定義Bean后置處理器,實(shí)現(xiàn)BeanPostProcessor接口
public class MyBeanProcessor implements BeanPostProcessor {
    // 初始化前執(zhí)行
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("☆☆☆ 后置處理器-初始化前:" + beanName + " = " + bean);
        return bean; // 必須返回bean實(shí)例,否則容器中無(wú)法獲取到該Bean
    }
    // 初始化后執(zhí)行
    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("★★★ 后置處理器-初始化后:" + beanName + " = " + bean);
        return bean;
    }
}

步驟2:將后置處理器注入IOC容器

后置處理器必須被IOC容器管理,才能生效。通過XML配置注入:

<!-- 注入Bean后置處理器 -->
<bean id="myBeanProcessor" class="com.gs.process.MyBeanProcessor"/>

3. 執(zhí)行效果說明

當(dāng)IOC容器初始化時(shí),會(huì)對(duì)所有Bean執(zhí)行以下流程:

Bean創(chuàng)建 → 屬性注入 → 后置處理器初始化前方法 → Bean初始化方法 → 后置處理器初始化后方法 → Bean就緒可用

控制臺(tái)會(huì)輸出類似如下內(nèi)容:

五、實(shí)戰(zhàn)測(cè)試:驗(yàn)證Bean生命周期流程

為了更直觀地理解整個(gè)生命周期流程,我們通過一個(gè)完整的測(cè)試案例來驗(yàn)證。

1. 測(cè)試類編寫

import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.xxx.Dog;
public class LifeCycleTest {
    @Test
    public void testLifeCycle() {
        System.out.println("-------容器初始化階段---------");
        // 初始化IOC容器(此時(shí)會(huì)觸發(fā)Bean的創(chuàng)建、屬性注入、初始化等流程)
        ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        System.out.println("-------對(duì)象使用階段---------");
        // 獲取Bean實(shí)例并使用
        Dog dog = ac.getBean("dog", Dog.class);
        System.out.println(dog);
        System.out.println("-------容器關(guān)閉階段---------");
        // 手動(dòng)關(guān)閉容器(觸發(fā)Bean的銷毀流程)
        ac.close(); // 注意:ApplicationContext接口無(wú)close方法,需使用其子類ClassPathXmlApplicationContext
    }
}

2. 測(cè)試結(jié)果與分析

控制臺(tái)輸出如下(結(jié)合注解方式和后置處理器):

輸出結(jié)果完全匹配我們之前拆解的生命周期階段,驗(yàn)證了流程的正確性。

六、核心知識(shí)點(diǎn)總結(jié)(面試必背)

  • Spring Bean生命周期8階段:創(chuàng)建 → 注入 → 初始化前 → 初始化 → 初始化后 → 就緒 → 銷毀 → 容器關(guān)閉;
  • 生命周期回調(diào)3種實(shí)現(xiàn)方式及優(yōu)先級(jí):注解(@PostConstruct/@PreDestroy)> 接口(InitializingBean/DisposableBean)> XML(init-method/destroy-method);
  • Bean后置處理器作用:全局?jǐn)r截所有Bean的初始化前后階段,實(shí)現(xiàn)增強(qiáng)邏輯,是AOP的基礎(chǔ);
  • 開發(fā)建議:優(yōu)先使用注解方式實(shí)現(xiàn)回調(diào),低耦合、高效率;避免使用接口方式,減少與Spring框架的耦合。

七、LomBok

通過本文的講解,相信大家已經(jīng)對(duì)Spring Bean的生命周期有了全面且深入的理解。建議結(jié)合文中的代碼案例實(shí)際運(yùn)行測(cè)試,通過輸出結(jié)果加深對(duì)各階段的記憶,面試時(shí)才能做到游刃有余!

到此這篇關(guān)于深度解析Spring Bean生命周期以及LomBok插件的文章就介紹到這了,更多相關(guān)Spring Bean生命周期內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

凯里市| 花垣县| 商南县| 榆林市| 乾安县| 安达市| 安义县| 工布江达县| 运城市| 安丘市| 苍山县| 通河县| 昭苏县| 砚山县| 洛浦县| 稷山县| 阜平县| 瓦房店市| 望都县| 尉犁县| 吉林省| 宣化县| 酉阳| 奉贤区| 合川市| 溧阳市| 夏河县| 菏泽市| 太康县| 普宁市| 柳河县| 都兰县| 遂平县| 蓝田县| 博乐市| 张掖市| 桦甸市| 佛坪县| 蒲城县| 镇坪县| 哈尔滨市|