Spring Bean有哪些生命周期回调方法?有哪几种实现方式?

你可能想问的是 Spring Bean 的生命周期回调方法。Spring Bean 生命周期回调是指 Bean 在初始化完成后、销毁前由 Spring 容器自动调用的方法,用于执行自定义逻辑(如资源初始化、释放连接等)。

一、核心生命周期回调方法

主要包含两类核心回调:

1.初始化回调:Bean 实例化(构造器调用)和属性注入完成后,Spring 自动调用,用于执行初始化逻辑(如初始化数据库连接池、加载配置文件)。

2.销毁回调:Bean 被容器销毁前(如容器关闭时),Spring 自动调用,用于执行资源释放逻辑(如关闭连接、释放文件句柄)。

二、回调方法的 4 种实现方式

1. 实现 Spring 提供的接口(接口回调)

通过实现 InitializingBean(初始化)和 DisposableBean(销毁)接口,重写固定方法,Spring 会自动识别并调用。

初始化:实现 InitializingBean 接口,重写 afterPropertiesSet() 方法(属性注入完成后调用)。

销毁:实现 DisposableBean 接口,重写 destroy() 方法(容器销毁 Bean 前调用)。

示例代码1:

csharp 复制代码
@Component
public class Book implements InitializingBean, DisposableBean {
    private String title;

    //空参
    public Book() {
        System.out.println("1.实例化 Book 对象");
    }

    //set
    @Value("Java 编程思想")
    public void setTitle(String title) {
        this.title = title;
        System.out.println("2.依赖注入(属性填充) 设置 Book 对象的 title 属性,title = " + title);
    }

    //get
    public String getTitle() {
        return title;
    }


    //初始化方法
    public void myInit() {
        if (title == null) {
            title = "默认书籍"; // 如果没有设置标题,则使用默认标题
            System.out.println("3.3 自定义初始化方法 Book 对象> 默认标题是:" + title);
        } else {
            System.out.println("3.3  自定义初始化方法 Book 对象> 标题是:" + title);
        }
    }

    //自定义初始化方法 PostConstruct
    @PostConstruct
    public void customInit() {
        System.out.println("3.1 PostConstruct初始化方法init1 Book 对象 -- init");
    }

    //自定义销毁方法
    @PreDestroy
    public void customDestroy() {
        System.out.println("5.1 Book 对象 -- PreDestroy");
    }

    //销毁方法
    public void myDestroy() {
        System.out.println("5.3 自定义销毁方法 Book 对象");
    }


    // InitializingBean 接口的方法
    public void afterPropertiesSet() throws Exception {
        System.out.println("3.2 InitializingBean初始化方法 Book 对象 -- afterPropertiesSet");
        if (title == null) {
            title = "默认书籍"; // 如果没有设置标题,则使用默认标题
//            System.out.println("4.1 初始化方法 Book 对象> 默认标题是:" + title);
        } else {
//            System.out.println("4.1 初始化方法 Book 对象> 标题是:" + title);
        }
    }

    // DisposableBean 接口的方法
    public void destroy() throws Exception {
        System.out.println("5.2 销毁方法 Book 对象 -- DisposableBean");
        // 在这里可以执行一些清理操作,例如关闭资源等

    }
}

2. 配置文件/注解指定自定义方法(自定义方法回调)

无需实现接口,而是通过 XML 配置或注解(@Bean)指定自定义的初始化/销毁方法名,Spring 会反射调用这些方法。

初始化方法:自定义任意方法(无参数、无返回值),通过配置指定为初始化回调。

销毁方法:自定义任意方法(无参数、无返回值),通过配置指定为销毁回调。

示例 1:XML 配置

xml 复制代码
<!-- 配置 Bean,指定 init-method(初始化)和 destroy-method(销毁) -->
<!--    定义一个book bean-->
<bean id="book" class="com.example.demo.bean.Book" init-method="myInit" destroy-method="myDestroy">
    <property name="title" value="Java编程思想"/>
</bean>

示例 2:@Bean 注解配置

less 复制代码
@Configuration // 使用 @Configuration 注解标记该类为配置类
@ComponentScan(basePackages = "com.example.demo.bean") // 扫描指定包下的组件
public class AppConfig {
    @Bean(initMethod = "myInit", destroyMethod = "myDestroy") // 定义一个 Bean,并指定初始化和销毁方法
    public Book book() {
        return new Book();
    }
}

// 自定义回调方法的 Bean

csharp 复制代码
public class Book {
    private String title;

//初始化方法
public void myInit() {
    if (title == null) {
        title = "默认书籍"; // 如果没有设置标题,则使用默认标题
        System.out.println("3.3 自定义初始化方法 Book 对象> 默认标题是:" + title);
    } else {
        System.out.println("3.3  自定义初始化方法 Book 对象> 标题是:" + title);
    }
}

//销毁方法
public void myDestroy() {
    System.out.println("5.3 自定义销毁方法 Book 对象");
}
// setter/getter 略
}

3. 使用 JSR-250 标准注解(注解回调)

通过 JSR-250 规范定义的 @PostConstruct(初始化)和 @PreDestroy(销毁)注解,直接标记在方法上,Spring 会自动扫描并调用(需确保 Spring 支持注解驱动,如配置 context:annotation-config/ 或 @ComponentScan)。

@PostConstruct:标记在初始化方法上,Bean 实例化+属性注入完成后调用。

@PreDestroy:标记在销毁方法上,Bean 被容器销毁前调用。

示例代码:

typescript 复制代码
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

@Component // 确保 Bean 被 Spring 扫描管理
public class Book {
 private String title;

//自定义初始化方法 PostConstruct
    @PostConstruct
    public void customInit() {
        System.out.println("3.1 PostConstruct初始化方法init1 Book 对象 -- init");
    }

    //自定义销毁方法
    @PreDestroy
    public void customDestroy() {
        System.out.println("5.1 Book 对象 -- PreDestroy");
    }

// setter/getter 略
}

4. 实现 BeanPostProcessor 接口(全局后置处理器)

BeanPostProcessor 是 Spring 的"Bean 后置处理器",作用于所有 Bean 的生命周期,可在 Bean 初始化前后插入自定义逻辑(注意:这是"全局回调",影响容器内所有 Bean,而非单个 Bean 的回调)。

postProcessBeforeInitialization:在 Bean 的初始化方法(如 afterPropertiesSet()、@PostConstruct)执行 前 调用。

postProcessAfterInitialization:在 Bean 的初始化方法执行 后 调用。

示例代码:

typescript 复制代码
@Component
public class BookProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) {
        // 在初始化之前执行
        if (bean instanceof Book) {
            System.out.println("2.5 -- Before Initialization: " + beanName);
        }
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        // 在初始化之后执行
        if (bean instanceof Book) {
            System.out.println("3.5 -- After Initialization: " + beanName);
        }
        return bean;
    }
}

测试接口:

csharp 复制代码
 @Test
    public void test4() {
        // 测试类
        //通过注解的方式生成bean的测试
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        // 获取 book 对象
        Book book = context.getBean(Book.class);
        // 4.使用bean
//        System.out.println("8.使用Bean  Cat 对象,name = " + cat.getName());
        System.out.println("4.使用Bean  Book 对象,name = " + book.getTitle());
        // 关闭容器
        context.close();
        // 5.销毁 Cat 对象
        // 注意:在使用 ClassPathXmlApplicationContext 时,销毁方法会在 close() 方法调用时自动执行
    }

测试结果如下:

lua 复制代码
1.实例化 Book 对象
2.依赖注入(属性填充) 设置 Book 对象的 title 属性,title = Java 编程思想
2.5 -- Before Initialization: book
3.1 PostConstruct初始化方法init1 Book 对象 -- init
3.2 InitializingBean初始化方法 Book 对象 -- afterPropertiesSet
3.3  自定义初始化方法 Book 对象> 标题是:Java 编程思想
3.5 -- After Initialization: book
4.使用Bean  Book 对象,name = Java 编程思想
5.1 Book 对象 -- PreDestroy
5.2 销毁方法 Book 对象 -- DisposableBean
5.3 自定义销毁方法 Book 对象

三、关键注意点

1.执行顺序(以单个 Bean 为例)

构造器调用 → 属性注入 → BeanPostProcessor.postProcessBeforeInitialization → 初始化回调(@PostConstruct/afterPropertiesSet()/自定义 init 方法) → BeanPostProcessor.postProcessAfterInitialization → Bean 就绪 → 容器关闭 → 销毁回调(@PreDestroy/destroy()/自定义 destroy 方法)。

2.销毁回调生效场景:仅单例 Bean 的销毁回调会被 Spring 自动调用(原型 Bean 每次获取都是新实例,容器不管理其销毁,需手动处理)。

相关推荐
沐怡旸13 小时前
【穿越Effective C++】条款14:在资源管理类中小心copying行为——RAII类的拷贝语义设计
c++·面试
程序定小飞13 小时前
基于springboot的web的音乐网站开发与设计
java·前端·数据库·vue.js·spring boot·后端·spring
舒一笑13 小时前
从手写周报到智能生成:PandaCoder如何让你的工作汇报效率提升10倍
后端·程序员·intellij idea
无名之辈J13 小时前
支付常犯错误
后端
沐怡旸13 小时前
【底层机制】ART虚拟机深度解析:Android运行时的架构革命
android·面试
申阳13 小时前
Day 6:04. 基于Nuxt开发博客项目-LOGO生成以及ICON图标引入
前端·后端·程序员
硅胶人13 小时前
[prowlarr][radarr][sonarr][qBitorrent]套件打造家庭影音中心
后端
JavaGuide13 小时前
OPPO 后端校招面试,过于简单了!
java·后端
调试人生的显微镜14 小时前
如何查看手机使用记录?四种实用方法详解
后端
侯爵14 小时前
rabbitmq 如何保证消息顺序消费
后端