一文理解SpringBean生命周期之PostConstruct、PreDestroy详解

概述想必大家在项目中都用过@PostConstruct这个注解把,知道它会在应用启动的时候执行被这个注解标注的方法 。其实它还有另外一个注解@PreDestroy,实在Bean销毁前执行,它们都是Bean生命周期的一环,那他们具体在什么阶段执行呢?我们从源码的角度带大家分析下 。
注解介绍@PostConstruct和@PreDestroy是JSR-250规范中定义的类两个类,表示Bean初始化后和销毁前指定的注解,位于JAVAx.annotation包下,而不是spring jar中的类 。
JSR-250, Java Specification Requests的缩写,意思是Java 规范提案 。它是Java界共同制定的一个重要标准 。它定义了一组通用的注解,比如@PostContruct, @Resource等,防止不同的J2EE组件比如Spring、JBoss、WebSphere等都各自实现一套注解 。
Spring作为一个NB的框架,它也遵循上面的规范,实现了对JSR注解的支持 。
@PostConstruct@Documented@Retention (RUNTIME)@Target(METHOD)public @interface PostConstruct {}

  • 该注解只能作用于方法上,执行依赖注入后执行任何初始化操作 。必须在类投入服务之前调用此方法 。
  • 应用PostConstruct的方法可以是公共的、受保护的、包私有的或私有的,但不能是静态的 。
  • 被注解方法不能有任何参数 。
@PreDestroy@Documented@Retention (RUNTIME)@Target(METHOD)public @interface PreDestroy {}
  • 作用于方法上,在容器销毁Bean的时候回调执行 。
  • 被注解方法不能有任何参数 。
  • 应用PreDestroy的方法可以是公共的、受保护的、包私有的或私有的,但不能是静态的 。
实战案例
  1. 定义bean
@Slf4j@ToStringpublic class LifeCycleBean implements InitializingBean {private String prop;public LifeCycleBean() {log.info("%%%%%%%%%%%%%%%%%%%% LifeCycleBean 实例化");}public LifeCycleBean(String prop) {this.prop = prop;}public String getProp() {return prop;}@PostConstructprivate void postContruct() {log.info("%%%%%%%%%%%%%%%%%%%% LifeCycleBean postContruct");}@PreDestroyprivate void preDestory() {log.info("%%%%%%%%%%%%%%%%%%%% LifeCycleBean preDestory");}public void setProp(String prop) {this.prop = prop;}public void init() {log.info("%%%%%%%%%%%%%%%%%%%% LifeCycleBean 初始化");this.setProp("hello");}public void destroy() {log.info("%%%%%%%%%%%%%%%%%%%% LifeCycleBean destroy");this.setProp("hello");}@Overridepublic void afterPropertiesSet() throws Exception {log.info("%%%%%%%%%%%%%%%%%%%% LifeCycleBean afterPropertiesSet");}}@Bean(name = "lifeCycleBean", initMethod = "init", destroyMethod = "destroy")public LifeCycleBean createLifeCycleBean() {return new LifeCycleBean();};定义了Bean初始化和销毁相关的方法,包括实现了InitializingBean接口,Bean配置了initMethod、destroyMethod属性,以及添加了@PostConstruct、@PreDestroy注解 。
  1. 查看执行结果

一文理解SpringBean生命周期之PostConstruct、PreDestroy详解

文章插图
 
代码地址:github.com/alvinlkk/sp…
  1. 小结
根据执行结果得知bean初始化和销毁的顺序:
  1. @PostContruct注解对应的方法
  2. 实现了InitializingBean接口的afterPropertiesSet方法
  3. Beaninit-method属性对应的方法
  4. @PreDestroy注解对应的方法
  5. Beandestroy-method属性对应的方法
源码解析
一文理解SpringBean生命周期之PostConstruct、PreDestroy详解

文章插图
 
通过debug快速追踪到实在Bean的初始化阶段 。
  1. AbstractAutowireCapableBeanFactory的initializeBean()方法是bean的初始化入口 。
  2. InitDestroyAnnotationBeanPostProcessorBean处理器中调用invokeInitMethods执行@PostContruct对应的方法 。
执行过程
一文理解SpringBean生命周期之PostConstruct、PreDestroy详解

文章插图
 

一文理解SpringBean生命周期之PostConstruct、PreDestroy详解

文章插图
 
在Bean的初始化过程前,会回调BeanPostProcessor的
postProcessBeforeInitialization方法,这是Spring的一个扩展点,而我们的@PostConstruct就是通过这种扩展机制实现的,它对应的类是InitDestroyAnnotationBeanPostProcessor 。
InitDestroyAnnotationBeanPostProcessor,顾名思义,它是用来处理初始化和销毁注解的一个Bean处理器,我们看下它的postProcessBeforeInitialization方法 。


推荐阅读