@PostConstruct 和 @PreDestroy

Spring Bean 生命周期管理
本文介绍如何使用@PostConstruct和@PreDestroy注解来管理Spring容器中Bean的生命周期,包括初始化后的操作及销毁前的清理工作。

Spring 容器中的 Bean 是有生命周期的,Spring 允许在 Bean 在初始化完成后以及 Bean 销毁前执行特定的操作,您既可以通过实现 InitializingBean/DisposableBean 接口来定制初始化之后 / 销毁之前的操作方法,也可以通过 <bean> 元素的 init-method/destroy-method 属性指定初始化之后 / 销毁之前调用的操作方法。关于 Spring 的生命周期,笔者在《精通 Spring 2.x—企业应用开发精解》第 3 章进行了详细的描述,有兴趣的读者可以查阅。

JSR-250 为初始化之后/销毁之前方法的指定定义了两个注释类,分别是 @PostConstruct 和 @PreDestroy,这两个注释只能应用于方法上。标注了 @PostConstruct 注释的方法将在类实例化后调用,而标注了 @PreDestroy 的方法将在类销毁之前调用。

package com.baobaotao;import javax.annotation.Resource;import javax.annotation.PostConstruct;import javax.annotation.PreDestroy;public class Boss { @Resource private Car car; @Resource(name = "office") private Office office; @PostConstruct public void postConstruct1(){ System.out.println("postConstruct1"); } @PreDestroy public void preDestroy1(){ System.out.println("preDestroy1"); } …}

 

您只需要在方法前标注 @PostConstruct@PreDestroy ,这些方法就会在 Bean 初始化后或销毁之前被 Spring 容器执行了。

我们知道,不管是通过实现 InitializingBean /DisposableBean 接口,还是通过 <bean> 元素的init-method/destroy-method 属性进行配置,都只能为 Bean 指定一个初始化 / 销毁的方法。但是使用@PostConstruct@PreDestroy 注释却可以指定多个初始化 / 销毁方法,那些被标注@PostConstruct@PreDestroy 注释的方法都会在初始化 / 销毁时被执行。

通过以下的测试代码,您将可以看到 Bean 的初始化 / 销毁方法是如何被执行的:


测试代码

                
package com.baobaotao;

import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AnnoIoCTest {

    public static void main(String[] args) {
        String[] locations = {"beans.xml"};
        ClassPathXmlApplicationContext ctx = 
            new ClassPathXmlApplicationContext(locations);
        Boss boss = (Boss) ctx.getBean("boss");
        System.out.println(boss);
        ctx.destroy();// 关闭 Spring 容器,以触发 Bean 销毁方法的执行
    }
}

 

这时,您将看到标注了 @PostConstructpostConstruct1() 方法将在 Spring 容器启动时,创建Boss Bean 的时候被触发执行,而标注了@PreDestroy 注释的preDestroy1() 方法将在 Spring 容器关闭前销毁Boss Bean 的时候被触发执行。

 

### @PostConstruct @PreDestroy 注解的用法及区别 #### 一、@PostConstruct 的功能与使用场景 `@PostConstruct` 是 Java 提供的一个标准注解,通常被用来定义 Bean 初始化完成后的回调方法。当 Spring 容器创建了一个 Bean 并完成了依赖注入之后,会自动调用标记有 `@PostConstruct` 的方法[^1]。 此注解的主要用途是在对象实例化并装配完成后执行一些额外的操作,比如资源加载、配置初始化或者状态校验等操作。需要注意的是,该方法必须是非静态的,并且不能带有任何参数[^2]。 ```java import javax.annotation.PostConstruct; public class ExampleService { private String message; public ExampleService(String message) { this.message = message; } @PostConstruct public void init() { System.out.println("Initializing bean with message: " + message); } } ``` #### 二、@PreDestroy 的功能与使用场景 相对应于 `@PostConstruct`,`@PreDestroy` 则是用来标注在 Bean 销毁前需要执行的方法上。它允许开发者清理资源或保存数据到持久存储中,确保程序退出时不会留下未处理的任务或泄露资源。 同样地,这个方法也应该是无参形式,并且由容器负责在其生命周期结束之前触发调用。 ```java import javax.annotation.PreDestroy; public class CleanupService { @PreDestroy public void cleanup() { System.out.println("Cleaning up resources..."); } } ``` #### 三、两者之间的主要差异 - **执行时机**:`@PostConstruct` 方法会在构造函数执行完毕以及属性设置好以后立即运行;而 `@PreDestroy` 方法则是在 Bean 被移除出 IoC 容器之前的瞬间被执行。 - **适用范围**:虽然它们都可以应用于任意类中的公共/受保护/私有的非静态方法之上,但是只有那些被声明为 Spring 管理下的 Beans 才能真正享受到这两个注解带来的便利效果。 #### 四、Spring 实现机制探讨 对于如何支持上述两个 JSR-250 规范内的注解,Spring内部通过 CommonAnnotationBeanPostProcessor 来识别处理这些特殊的 Lifecycle Callbacks 。这意味着如果希望项目能够正常使用此类特性,则需确保已注册相应的处理器组件至上下文中。 ```xml <bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"/> ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值