概述想必大家在项目中都用过@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的方法可以是公共的、受保护的、包私有的或私有的,但不能是静态的 。
- 被注解方法不能有任何参数 。
@Documented@Retention (RUNTIME)@Target(METHOD)public @interface PreDestroy {}
- 作用于方法上,在容器销毁Bean的时候回调执行 。
- 被注解方法不能有任何参数 。
- 应用PreDestroy的方法可以是公共的、受保护的、包私有的或私有的,但不能是静态的 。
- 定义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注解 。- 查看执行结果
文章插图
代码地址:github.com/alvinlkk/sp…
- 小结
- @PostContruct注解对应的方法
- 实现了InitializingBean接口的afterPropertiesSet方法
- Beaninit-method属性对应的方法
- @PreDestroy注解对应的方法
- Beandestroy-method属性对应的方法
文章插图
通过debug快速追踪到实在Bean的初始化阶段 。
- AbstractAutowireCapableBeanFactory的initializeBean()方法是bean的初始化入口 。
- InitDestroyAnnotationBeanPostProcessorBean处理器中调用invokeInitMethods执行@PostContruct对应的方法 。
文章插图
文章插图
在Bean的初始化过程前,会回调BeanPostProcessor的
postProcessBeforeInitialization方法,这是Spring的一个扩展点,而我们的@PostConstruct就是通过这种扩展机制实现的,它对应的类是InitDestroyAnnotationBeanPostProcessor 。
InitDestroyAnnotationBeanPostProcessor,顾名思义,它是用来处理初始化和销毁注解的一个Bean处理器,我们看下它的postProcessBeforeInitialization方法 。
推荐阅读
- 欲速则不达的意思,欲速则不达的理解-
- 呆若木鸡理解,呆若木鸡背后的大道理-
- |看了马思纯的早期生活照,我理解了什么是真正的“又纯又欲”
- 如何理解曹操说的生子当如孙仲谋,曹操生子当如孙仲谋上一句-
- 对爱情的理解和感受,对爱情的理解是什么-
- 什么叫做无欲则刚,无欲则刚怎么理解-
- 有好儿子不如有好媳妇怎么理解,有个好儿子不如有个好媳妇什么意思-
- 关于孔子对于仁和礼的理解,孔子认为“仁”和“礼”是互为表征的,仁是礼的本质-
- 怎么理解贫贱夫妻百事哀,贫贱夫妻百事哀中的哀怎么读-_1
- 梦溪笔谈阅读理解及答案,《梦溪笔谈》受到的启示-