Spring ApplicationContext 的生命周期钩子探究

Spring 提供了多种方法实现 Bean 在初始化和销毁时的回调:

  • JSR-250 标准提供了一对注解 @PostConstruct@PreDestroy,用于在类中标识某方法为生命周期钩子。
  • 实现了 InitializingBean 接口,可以在 afterPropertiesSet() 方法里做初始化之后的任务。实现了 DisposableBean 接口,可以在 destroy() 方法里做销毁前的任务。
  • 在配置 XML 或者 @Bean 注解中,通过 init-methoddestroy-method 属性也可以声明生命周期钩子。

初始化之后指对象创建、注入工作结束、其他配置结束后。

执行顺序为:

// 初始化之后
Constructor > @PostConstruct > InitializingBean > init-method

// 销毁前
@PreDestroy > DisposableBean > destroy-method

若想在优雅关闭容器时依次销毁单例,需使用 ConfigurableApplicationContext 类提供的 registerShutdownHook() 方法。

探究生命周期钩子的执行顺序

执行顺序可以在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory 类里找到。

以初始化为例,看 initializeBean()

  1. invokeAwareMethods()
  2. applyBeanPostProcessorsBeforeInitialization()
  3. invokeInitMethods()
  4. applyBeanPostProcessorsAfterInitialization()

然后看到 invokeInitMethods() 方法里有识别 InitializingBean 接口并调用 afterPropertiesSet() 的逻辑,之后有 invokeCustomInitMethod() 的方法完成 init-method 的逻辑。

而 JSR-250 标准是在 org.springframework.context.annotation.CommonAnnotationBeanPostProcessor 类中定义:

public CommonAnnotationBeanPostProcessor() {   
       setOrder(Ordered.LOWEST_PRECEDENCE - 3);   
       setInitAnnotationType(PostConstruct.class);   
       setDestroyAnnotationType(PreDestroy.class);   
       ignoreResourceType("javax.xml.ws.WebServiceContext");   
} 

CommonAnnotationBeanPostProcessor 继承自 InitDestroyAnnotationBeanPostProcessor 类,这个类有以下很有意思的方法:

  • postProcessBeforeInitialization() 来自 BeanPostProcessor 接口
  • postProcessAfterInitialization() 来自 BeanPostProcessor 接口
  • postProcessBeforeDestruction() 来自 DestructionAwareBeanPostProcessor 接口

能看到 postProcessBeforeInitialization()postProcessBeforeDestruction() 会先调用 findLifecycleMetadata(),它会调用 buildLifecycleMetadata() 构造生命周期元信息。

buildLifecycleMetadata() 方法里会寻找满足 initAnnotationTypedestroyAnnotationType 的注解,并加入列表

回过头看 initializeBean() 先调用了 applyBeanPostProcessorsBeforeInitialization(),所以 JSR-250 的 @PostConsturct 优先执行。

转载于:https://my.oschina.net/tridays/blog/864608

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值