1. 简介

Spring 提供了在 Bean 创建和销毁 时执行自定义逻辑的能力。比如,我们可以通过实现 InitializingBeanDisposableBean 接口来完成初始化或销毁操作。

本文将介绍另一种更灵活的方式:使用 @PostConstruct@PreDestroy 注解。

2. @PostConstruct

Spring 在 Bean 属性初始化完成后,仅调用一次被 @PostConstruct 标注的方法

即使没有需要初始化的内容,该方法也会被执行。需要注意的是:

  • 该方法可以是任意访问级别(public、private、protected)
  • ❌ 但不能是 static 方法

一个常见的使用场景是:在开发阶段向数据库中插入一些默认数据:

@Component
public class DbInit {

    @Autowired
    private UserRepository userRepository;

    @PostConstruct
    private void postConstruct() {
        User admin = new User("admin", "admin password");
        User normalUser = new User("user", "user password");
        userRepository.save(admin, normalUser);
    }
}

上面这段代码会在 UserRepository 初始化完成后,自动执行 postConstruct() 方法,完成默认用户的插入。

3. @PreDestroy

Spring 在销毁 Bean 之前,会调用一次被 @PreDestroy 标注的方法

@PostConstruct 类似:

  • 方法可以是任意访问级别
  • ❌ 同样不能是 static 方法
@Component
public class UserRepository {

    private DbConnection dbConnection;

    @PreDestroy
    public void preDestroy() {
        dbConnection.close();
    }
}

这个方法通常用于释放资源,比如关闭数据库连接、清理缓存等。

4. javax.annotation 还是 jakarta.annotation?

从 JDK 6 到 JDK 8,@PostConstruct@PreDestroy 都属于标准 Java 库的一部分,位于 javax.annotation 包下。

⚠️ 但从 JDK 9 开始,整个 javax.annotation 包被移出了核心模块,并在 JDK 11 中被彻底移除。

在 Jakarta EE 9 中,该包被迁移到了 jakarta.annotation

那么问题来了:我该用 javax.annotation 还是 jakarta.annotation

✅ 答案是:看你用的 Spring 版本

下面这张表总结了 Spring、JDK 和注解命名空间之间的兼容性:

Spring 版本 JDK 版本 Java / Jakarta 命名空间
6.1.x JDK 17 - JDK 23 jakarta
6.0.x JDK 17 - JDK 21 jakarta
5.3.x JDK 8 - JDK 21 javax

从表中可以看出:

  • Spring 6.0.x 和 6.1.x 使用的是 jakarta 命名空间
  • 如果你使用的是 Spring 5.3.x 并且 JDK 9 及以上版本,则必须显式添加 javax.annotation-api 依赖:
<dependency>
    <groupId>javax.annotation</groupId>
    <artifactId>javax.annotation-api</artifactId>
    <version>1.3.2</version>
</dependency>

这段 XML 展示了如何在 Maven 项目的 pom.xml 中添加 javax.annotation-api 依赖。

5. 总结

在这篇文章中,我们介绍了如何使用 @PostConstruct@PreDestroy 注解来控制 Bean 的初始化和销毁逻辑。

这两个注解虽然简单,但在实际开发中非常实用,特别是在需要做一些初始化或资源清理的场景下。

一如既往,所有示例代码都可以在 GitHub 上找到。


原始标题:Spring PostConstruct and PreDestroy Annotations | Baeldung