@PostConstruct和@PreDestroy是一种JSR-250的规范。适用的方法可以是public, protected,package private or private。不能是static修饰的,可以是final修饰的。
@PostConstruct:被@PostConstruct修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器调用一次,类似于Servlet的init()方法。被@PostConstruct修饰的方法会在构造函数之后,init()方法之前运行。
@PreDestroy:被@PreConstruct修饰的方法会在服务器卸载Servlet的时候运行,并且只会被服务器调用一次,类似于Servlet的destroy()方法。被@PreConstruct修饰的方法会在destroy()方法之后运行,在Servlet被彻底卸载之前。我们可以通过调用容器的close()方法来测试:
ConfigurableApplicationContext ac = SpringApplication.run(Application.class, args);
ac.close();
使用示例
在一个常量类中我们想读取配置文件的某个属性值,然后在其他的类中使用,这个时候如果把变量定义为static,那么通过@Value注解就获取不到,因此我们可以另外定义一个static变量,然后在@PostConstruct注解的方法中给这个static变量赋值。
@Component
public class SystemConstant {
private static String UPLOAD_PATH;
@Value("${file.uploadPath}")
private String uploadPath;
@PostConstruct
private final void init(){
System.out.println("uploadPath======="+uploadPath);
UPLOAD_PATH = uploadPath;
System.out.println("UPLOAD_PATH======="+UPLOAD_PATH);
}
@PreDestroy
private final void destroy(){
System.out.println("destroy");
}
}
如果我们在其中通过@Autowired注入bean,
@Component
public class SystemConstant {
@Autowired
private RedisUtil redisUtil;
public SystemConstant(){
System.out.println("SystemConstant构造器中打印redisUtil====="+redisUtil);
}
private static String UPLOAD_PATH;
@Value("${file.uploadPath}")
private String uploadPath;
@PostConstruct
private final void init(){
System.out.println("PostConstruct中打印redisUtil====="+redisUtil);
UPLOAD_PATH = uploadPath;
System.out.println("UPLOAD_PATH======="+UPLOAD_PATH);
}
@PreDestroy
private final void destroy(){
System.out.println("destroy");
}
}
打印结果表明执行顺序如下:
Constructor >> @Autowired >> @PostConstruct
重要: @PostConstruct和@PreDestroy 已经完全在Java 11中删除.
要继续使用它们,您需要添加注释-API JAR到您的依赖项
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>