PostConstruct 和 PreDestroy 注解

1、简介

Spring 允许我们在 Bean 的创建和销毁时执行自定义操作。例如,可以让 Bean 实现 InitializingBeanDisposableBean 接口,从而在创建和销毁时触发回调方法。

本文将带你了解第二种实现方式,即使用 @PostConstruct@PreDestroy 注解。

2、@PostConstruct

Spring 只会在 Bean 属性初始化后调用一次注解了 @PostConstruct 的方法。即使没有任何属性需要初始化,这些方法也会运行。

使用 @PostConstruct 注解的方法可以用任何访问级别,但不能是静态的。

@PostConstruct 一个可能的用途是填充数据。例如,在开发过程中,我们想创建一些默认用户:

@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 从 Application Context 中删除之前,会运行一次注解了 @PreDestroy 的方法。

@PostConstruct 一样,注解为 @PreDestroy 的方法可以有任何访问级别,但不能是静态的。

@Component
public class UserRepository {

    private DbConnection dbConnection;
    @PreDestroy
    public void preDestroy() {
        // 释放 DB 连接
        dbConnection.close();
    }
}

该方法的目的应该是在 Bean 被销毁之前释放资源或执行其他清理任务,如关闭数据库连接。

4、用 javax.annotation 还是 jakarta.annotation?

从 JDK 6 到 JDK 8,@PostConstruct@PreDestroy 注解是标准 Java 库中 javax.annotation 包的一部分。但是,从 JDK 9 开始,整个 javax.annotation 包从核心 Java 模块中移除,并在 JDK 11 中完全取消。在 Jakarta EE 9 中,该包被重新命名为 jakarta.annotation

因此,到底应该使用 javax.annotation 还是 jakarta annotation 的注解?这取决于使用的 Spring 版本。

Spring、JDK、javax 和 jakarta 命名空间之间的兼容性如下表:

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

如上表所示,在 Spring 6.0.x6.1.x 中,我们应使用 jakarta 命名空间。但是,如果我们的项目使用了 Spring 5.3.xJDK 9 或更高版本,由于 Spring 5.3.x 仅支持 javax 命名空间,我们必须在项目中明确添加 javax.annotation-api 依赖:

<dependency>
    <groupId>javax.annotation</groupId>
    <artifactId>javax.annotation-api</artifactId>
    <version>1.3.2</version>
</dependency>

5、总结

本文介绍了如何使用 @PostConstruct@PreDestroy 注解来在 Bean 的初始化和销毁时执行回调方法,还介绍了 Spring、JDK、javax 和 jakarta 命名空间之间的兼容性。


Ref:https://www.baeldung.com/spring-postconstruct-predestroy