spring 声明周期钩子方法 扩展点、@PostConstruct、InitializingBean、AbstractAutowireCapableBeanFactory、CommonAnnotat

本文介绍了Spring Bean生命周期钩子方法,包括3种钩子方法的执行顺序,即先执行Java规范的,再是Spring接口,最后是自定义方法。钩子方法在属性依赖注入完毕后执行,与proxy解耦。还阐述了其实现原理,如@PostConstruct通过CommonAnnotationBeanPostProcessor执行,InitializingBean及自定义方法通过AbstractAutowireCapableBeanFactory实现。

spring bean生命周期钩子方法执行顺序

spring bean生命周期钩子方法一共有3种,执行顺序如下

  • @PostConstruct (javax.annotation)、@PreDestroy(javax.annotation)
  • InitializingBean#afterPropertiesSet(org.springframework.beans.factory) 、DisposableBean#destroy(org.springframework.beans.factory) 回调接口
  • 自定义 init() 、destroy() 方法

怎么去记这个顺序呢?这里以初始化来举例。
可以这样理解,越标准的越先执行,那么属于java规范的@PostConstruct首先执行;而后spring接口InitializingBean#afterPropertiesSet ,最后才是自定义的方法。
销毁时同理,所以执行顺序依次是属于java规范的的@PreDestroy、接口DisposableBean#destroy、最后自定义destroy方法。

钩子方法执行时机

钩子方法在属性依赖注入完毕后执行,并且操作的raw bean reference,而不是proxy bean,这样可以使生命周期方法与proxy解耦。

自定义init、destory举例

  • xml中定义
    • <bean id="exampleInitBean" class="examples.ExampleBean" init-method="init"/>
  • @Bean注解中指定
    • 如下
public class BeanOne {
   
   

    public void init() {
   
   
        // initialization logic
    }
}
public class BeanTwo {
   
   

    public void cleanup() {
   
   
        // destruction logic
    }
}

@Configuration
public class AppConfig {
   
   

    @Bean(initMethod = "init")
    public BeanOne beanOne() {
   
   
        return new BeanOne();
    }

    @Bean(destroyMethod = "cleanup")
    public BeanTwo beanTwo() {
   
   
        return new BeanTwo();
    }
}

生命周期钩子方法的实现原理

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
先注入依赖属性,然后执行生命周期钩子方法。

//注入依赖属性,@AutoWired、@Resource
populateBean(beanName, mbd, instanceWrapper);
// 执行生命周期钩子方法
exposedObject = initializeBean(beanName, exposedObject, mbd);

继续跟踪AbstractAutowireCapableBeanFactory#initializeBean

//通过CommonAnnotationBeanPostProcessor执行的@PostConstruct、@PreDestroy
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
// 执行InitializingBean、自定义钩子方法
invokeInitMethods(beanName, wrappedBean, mbd);

上边两行分别对应下边的两个标题 @PostConstruct的实现原理InitializingBean、自定义init方法实现原理

@PostConstruct的实现原理

AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization,执行了BeanPostProcessor#postProcessBeforeInitialization

public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值