目录

1. 注解说明

2. 调用过程

3. 调用分析


1. 注解说明

@PostConstruct,@PreDestroy是Java规范JSR-250引入的注解,定义了对象的创建和销毁工作,同一期规范中还有注解@Resource,Spring也支持了这些注解;

在Spring中,@PostConstruct,@PreDestroy注解的解析是通过BeanPostProcessor实现的,具体的解析类是org.springframework.context.annotation.CommonAnnotationBeanPostProcessor,其父类是org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor,Spring官方说明了该类对JSR-250中@PostConstruct,@PreDestroy,@Resource注解的支持:

Spring's org.springframework.context.annotation.CommonAnnotationBeanPostProcessor supports the JSR-250 javax.annotation.PostConstruct and javax.annotation.PreDestroy annotations out of the box, as init annotation and destroy annotation, respectively. Furthermore, it also supports the javax.annotation.Resource annotation for annotation-driven injection of named beans.

2. 调用过程

具体过程是,先IOC容器先解析各个组件的定义信息,解析到@PostConstruct,@PreDestroy的时候,定义为生命周期相关的方法,组装组件的定义信息等待初始化;在创建组件时,创建组件并且属性赋值完成之后,在执行各类初始化方法之前,从容器中找出所有BeanPostProcessor的实现类,其中包括InitDestroyAnnotationBeanPostProcessor,执行所有BeanPostProcessor的postProcessBeforeInitialization方法,在InitDestroyAnnotationBeanPostProcessor中就是找出被@PostConstruct修饰的方法的定义信息,并执行被@PostConstruct标记的方法;

3. 调用分析

@PostConstruct的调用链如下:

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(String, Object, RootBeanDefinition)初始化流程中,先执行org.springframework.beans.factory.config.BeanPostProcessor.postProcessBeforeInitialization(Object, String)方法,然后再执行初始化方法:

protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {if (System.getSecurityManager() != null) {AccessController.doPrivileged(new PrivilegedAction<Object>() {@Overridepublic Object run() {invokeAwareMethods(beanName, bean);return null;}}, getAccessControlContext());}else {invokeAwareMethods(beanName, bean);}Object wrappedBean = bean;if (mbd == null || !mbd.isSynthetic()) {// 在执行初始化方法之前:先执行org.springframework.beans.factory.config.BeanPostProcessor.postProcessBeforeInitialization(Object, String)方法wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}try {//执行InitializingBean的初始化方法和init-method指定的初始化方法invokeInitMethods(beanName, wrappedBean, mbd);}catch (Throwable ex) {throw new BeanCreationException((mbd != null ? mbd.getResourceDescription() : null),beanName, "Invocation of init method failed", ex);}if (mbd == null || !mbd.isSynthetic()) {wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);}return wrappedBean;
}

org.springframework.beans.factory.config.BeanPostProcessor.postProcessBeforeInitialization(Object, String)的说明如下:

Apply this BeanPostProcessor to the given new bean instance before any bean initialization callbacks (like InitializingBean's afterPropertiesSet or a custom init-method). The bean will already be populated with property values. The returned bean instance may be a wrapper around the original.

调用时机: 在组件创建完属性复制完成之后,调用组件初始化方法之前;

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(Object, String)的具体流程如下:

@Override
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)throws BeansException {Object result = existingBean;for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {//遍历所有BeanPostProcessor的实现类,执行BeanPostProcessor的postProcessBeforeInitialization//在InitDestroyAnnotationBeanPostProcessor中的实现是找出@PostConstruct标记的方法的定义信息,并执行result = beanProcessor.postProcessBeforeInitialization(result, beanName);if (result == null) {return result;}}return result;
}

@PreDestroy调用链如下:

@PreDestroy是通过org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor.postProcessBeforeDestruction(Object, String)被调用(InitDestroyAnnotationBeanPostProcessor实现了该接口),该方法的说明如下:

Apply this BeanPostProcessor to the given bean instance before its destruction. Can invoke custom destruction callbacks.

Like DisposableBean's destroy and a custom destroy method, this callback just applies to singleton beans in the factory (including inner beans).

调用时机: 该方法在组件的销毁之前调用;

org.springframework.beans.factory.support.DisposableBeanAdapter.destroy()的执行流程如下:

@Override
public void destroy() {if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {//调用所有DestructionAwareBeanPostProcessor的postProcessBeforeDestruction方法for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {processor.postProcessBeforeDestruction(this.bean, this.beanName);}}if (this.invokeDisposableBean) {if (logger.isDebugEnabled()) {logger.debug("Invoking destroy() on bean with name '" + this.beanName + "'");}try {if (System.getSecurityManager() != null) {AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {@Overridepublic Object run() throws Exception {((DisposableBean) bean).destroy();return null;}}, acc);}else {//调用DisposableBean的销毁方法((DisposableBean) bean).destroy();}}catch (Throwable ex) {String msg = "Invocation of destroy method failed on bean with name '" + this.beanName + "'";if (logger.isDebugEnabled()) {logger.warn(msg, ex);}else {logger.warn(msg + ": " + ex);}}}//调用自定义的销毁方法if (this.destroyMethod != null) {invokeCustomDestroyMethod(this.destroyMethod);}else if (this.destroyMethodName != null) {Method methodToCall = determineDestroyMethod();if (methodToCall != null) {invokeCustomDestroyMethod(methodToCall);}}
}

所以是先调用DestructionAwareBeanPostProcessor的postProcessBeforeDestruction(@PreDestroy标记的方法被调用),再是DisposableBean的destory方法,最后是自定义销毁方法;

Spring生命周期注解之@PostConstruct,@PreDestroy相关推荐

  1. Spring生命周期——简介

    文章目录 Spring生命周期 1 Bean 生命周期的整个执行过程描述如下: 2 Spring中的循环依赖是怎么处理的 3 重写Spring生命周期中的接口方法: Spring生命周期 Spring ...

  2. Spring 生命周期回调机制

    一.Spring 生命周期回调机制可选方式 Spring官方文档注明从Spring 2.5开始,您可以使用三种方式来控制Bean生命周期行为: InitializingBean和DisposableB ...

  3. spring生命周期七个过程_Spring杂文(三)Spring循环引用

    众所周知spring在默认单例的情况下是支持循环引用的 Appconfig.java类的代码 @Configurable @ComponentScan("com.sadow") p ...

  4. Spring生命周期

    学习心得 1,学习spring生命周期是很有必要的,知道bean的创建过程,在实际项目中可以解决一些启动遇到的问题 2,通过案例代码运行一遍理解会很快记住整个流程,不需要强记 3,为了节约学习成本,案 ...

  5. Spring生命周期Bean初始化过程详解

    Spring生命周期Bean初始化过程详解 Spring 容器初始化 Spring Bean初始化 BeanFactory和FactoryBean 源码分析 Bean的实例化 preInstantia ...

  6. 【SSM - Spring篇01】spring详细概述,Spring体系结构,bean、property属性,Spring生命周期方法

    文章目录 1. Spring介绍 2. Spring体系架构 2.1 Spring核心容器(Core Container) 2.2 数据访问/集成(Data Access/Integration) 2 ...

  7. Spring 生命周期详解

    Spring 生命周期详解 一.传统JAVA bean的生命周期 使用Java关键字 new 进行Bean 的实例化,然后该Bean 就能够使用了. 一旦bean不再被使用,则由Java自动进行垃圾回 ...

  8. 【Java从0到架构师】Spring - 生命周期、代理

    生命周期.代理 bean 的生命周期 代理 业务层的一些问题 静态代理 (Static Proxy) 动态代理 (Dynamic Proxy) JDK 动态代理 - Proxy.newProxyIns ...

  9. 老司机带你从源码开始撸Spring生命周期!!!

    导读 Spring在Java Web方面有着举足轻重的地位,spring的源码设计更是被很多开发者所惊叹,巧妙的设计,精细的构思,都注定他的地位.今天陈某大言不惭的带你来从源码角度解析Spring的生 ...

最新文章

  1. Ubuntu13.04 配置smb服务器-new
  2. python常用输入输出の方法
  3. 如何利用计算机模拟分子生物学,虚拟分子生物学学习实验室构建
  4. 使用Ext.grid.Panel生成表格
  5. 文华财经彩波均线主图指标公式(指标公式源码)破解加密
  6. 【Qt for Python官方教程】使用pyside6-rcc引入.qrc文件
  7. 2012年最具影响力路由器配置精品文章荟萃【108篇】
  8. JavaWeb宿舍管理系统环境搭建运行教程
  9. python:假设一年期定期利率为3.25%,计算一下需要过多少年,一万元的一年定期存款连本带息能翻番?
  10. mac连接wifi无ip/无法访问网络
  11. 自制COCO 实例分割dataset并测试效果(从采集到测试)
  12. 机器学习三剑客之Matplotlab
  13. day1 - SDK入门
  14. AMCL定位融合UWB
  15. Unable to negotiate with xxxx port 22
  16. 电赛综合测评题练习(二)-(与2015年电赛综合测评要求类似)
  17. PLC简单梯形图(一)
  18. 天之骄子还是平凡之路
  19. hao123毒瘤太霸道了,必须这样除掉。
  20. 计算机网络传输层课件,计算机网络基椽第八章(传输层)(全)ppt培训课件

热门文章

  1. 【JavaScript】写程序编程基础入门
  2. 大卫 异星觉醒 机器人_《异星觉醒》定档 高智商外星生物惊世浩劫
  3. 无法访问计算机上的默认网站,教你如何禁止打开某个网页、禁止访问某个网站...
  4. 量化学习——跟随龙虎榜交易
  5. google pay
  6. uniapp 微信小程序转盘指针抽奖
  7. 使用html+css实现一个静态页面(化妆品公司 5页_含源码)
  8. 【Python爬虫实战】获取2018年重庆智博会参会企业名单,用于市场洞察
  9. Immutable List
  10. angular路由的js跳转