前言
源码
@Documented
@Retention (RUNTIME)
@Target(METHOD)
public @interface PostConstruct {
}
@Documented
@Retention (RUNTIME)
@Target(METHOD)
public @interface PreDestroy {
}
@PostConstruct
@PostConstruct注解好多人以为是Spring提供的。其实是Java自己的注解。从源码可以看出,@PostConstruct注解是Java中的注解,并不是Spring提供的注解。
@PostConstruct注解被用来修饰一个非静态的void()方法。被@PostConstruct修饰的方法会在服务器加载Servlet的时候运行,并且只会被服务器执行一次。PostConstruct在构造函数之后执行,init()方法之前执行。
通常我们会是在Spring框架中使用到@PostConstruct注解,该注解的方法在整个Bean初始化中的执行顺序:
Constructor(构造方法) -> @Autowired(依赖注入) -> @PostConstruct(注释的方法)。
@PreDestroy注解
被@PreDestroy修饰的方法会在服务器卸载Servlet的时候运行,并且只会被服务器调用一次,类似于Servlet的destroy()方法。被@PreDestroy修饰的方法会在destroy()方法之后运行,在Servlet被彻底卸载之前。执行顺序如下所示。
调用destroy()方法->@PreDestroy->destroy()方法->bean销毁。
总结:@PostConstruct,@PreDestroy是Java规范JSR-250引入的注解,定义了对象的创建和销毁工作,同一期规范中还有注解@Resource,Spring也支持了这些注解。
测试案例
package com.lyj.demo.pojo;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
/**
* @author 凌兮
* @date 2021/4/14 9:34
* @PostConstruct 和 @PreDestroy 注释使用测试
*/
public class Cat {
public Cat() {
System.out.println("cat 构造器执行");
}
public void init() {
System.out.println("cat init 方法执行");
}
@PostConstruct
public void postConstruct() {
System.out.println("cat @PostConstruct 注解标注的方法执行");
}
@PreDestroy
public void preDestroy() {
System.out.println("cat @PreDestroy 注解标注的方法执行");
}
public void destroy() {
System.out.println("cat destroy 方法执行");
}
}
package com.lyj.demo.pojo;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
/**
* @author 凌兮
* @date 2021/4/14 9:46
*/
@Component
public class AnimalConfig {
/**
* 将Cat注入到Spring Bean里,
* @return
*/
@Bean(initMethod = "init", destroyMethod = "destroy")
public Cat cat() {
return new Cat();
}
}
/**
* @PostConstruct 和 @PreDestroy 注释使用测试
*/
@Test
public void postConstruct() {
// 创建IOC容器
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AnimalConfig.class);
// 关闭IOC容器
context.close();
}
结果
总结
从输出的结果信息中,可以看出执行的顺序是: 构造方法 -> @PostConstruct -> init()方法 -> @PreDestroy -> destroy()方法。