Spring @PostConstruct注解学习

一. 介绍

@PostConstruct 注解在我们日常开发中用的很多,它的执行时机是在 Bean 构造方法执行后、populate() 属性注入完成后执行的;

二. 使用

@PostConstruct 注解的简单使用如下:

@Component
@Slf4j
public class Bean03 {

    @Autowired
    private Bean01 bean01;

    @Autowired
    private Bean02 bean02;

    @PostConstruct
    public void postConstruct() {
        log.info("Bean03 的 postConstruct()");
    }
}

三. 源码

我们知道 @PostContruct 注解注解的方法的执行时机是:构造方法 -> populate -> @PostConstruct -> initMethod;

也就是属性注入完成后会执行,我们从 Spring 的 getBean() 看 @PostConstruct 的执行时机;

我们直接点进 BeanFactory 的 doCreateBean();

// ----------------------------- AbstractAutowireCapableBeanFactory ---------------------------
protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    // 1. 执行 bean 的构造方法构造出 Bean 对象
    BeanWrapper instanceWrapper = null;
    if (mbd.isSingleton()) {
        instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
    }
    if (instanceWrapper == null) {
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    Object bean = instanceWrapper.getWrappedInstance();
    Class<?> beanType = instanceWrapper.getWrappedClass();
    if (beanType != NullBean.class) {
        mbd.resolvedTargetType = beanType;
    }

    // ...

    Object exposedObject = bean;
    try {
        // 2. 执行属性注入
        populateBean(beanName, mbd, instanceWrapper);
        
        // 3. 执行 bean 的初始化
        // 我们直接看 initializeBean()
        exposedObject = initializeBean(beanName, exposedObject, mbd);
    }
    catch (Throwable ex) {
        throw ex;
    }

    // ...

    try {
        // 4. 注册注销 bean
        registerDisposableBeanIfNecessary(beanName, bean, mbd);
    }
    catch (BeanDefinitionValidationException ex) {
        throw new BeanCreationException(
            mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
    }

    return exposedObject;
}




// ----------------------------- AbstractAutowireCapableBeanFactory ---------------------------
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    invokeAwareMethods(beanName, bean);

    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
        // 1. 执行 beanPostProcessor 的 postProcessBeforeInitialization()
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }

    try {
        // 2. 执行 bean 的 initMethod
        invokeInitMethods(beanName, wrappedBean, mbd);
    }
    catch (Throwable ex) {
        throw new BeanCreationException(
            (mbd != null ? mbd.getResourceDescription() : null), beanName, ex.getMessage(), ex);
    }
    if (mbd == null || !mbd.isSynthetic()) {
        // 3. 执行 beanPostProcessor 的 postProcessAfterInitialization()
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }

    return wrappedBean;
}

对于 @PostConstruct 注解来说,解析的 BeanPostProcessor 是 InitDestroyAnnotationBeanPostProcessor;

我们直接看它的 postProcessBeforeInitialization();

// --------------------------- InitDestroyAnnotationBeanPostProcessor -----------------------
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    // 1. 获取 bean 类的生命周期元数据
    LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
    try {
        // 2. 执行元数据的初始化方法
        // 也就是执行 bean 对应的 postContruct()/preDestroy()
        metadata.invokeInitMethods(bean, beanName);
    } catch (Throwable ex) {
        throw new BeanCreationException(beanName, "Failed to invoke init method", ex);
    }
    return bean;
}



// --------------------------- InitDestroyAnnotationBeanPostProcessor -----------------------
private LifecycleMetadata findLifecycleMetadata(Class<?> beanClass) {
    if (this.lifecycleMetadataCache == null) {
        return buildLifecycleMetadata(beanClass);
    }
    LifecycleMetadata metadata = this.lifecycleMetadataCache.get(beanClass);
    if (metadata == null) {
        synchronized (this.lifecycleMetadataCache) {
            metadata = this.lifecycleMetadataCache.get(beanClass);
            if (metadata == null) {
                // 构造 bean 类的生命周期元数据
                metadata = buildLifecycleMetadata(beanClass);
                this.lifecycleMetadataCache.put(beanClass, metadata);
            }
            return metadata;
        }
    }
    return metadata;
}





// --------------------------- InitDestroyAnnotationBeanPostProcessor -----------------------
private LifecycleMetadata buildLifecycleMetadata(final Class<?> clazz) {
    // 初始化方法集合
    List<LifecycleElement> initMethods = new ArrayList<>();
    // 销毁方法集合
    List<LifecycleElement> destroyMethods = new ArrayList<>();
    Class<?> targetClass = clazz;

    do {
        final List<LifecycleElement> currInitMethods = new ArrayList<>();
        final List<LifecycleElement> currDestroyMethods = new ArrayList<>();

        // 收集目标 clazz 的本地方法(本地方法即不包含从父类继承的)
        ReflectionUtils.doWithLocalMethods(targetClass, method -> {
            // 收集 init 类型注解标记的方法,至初始化方法集合中
            if (method.isAnnotationPresent(this.initAnnotationType)) {
                LifecycleElement element = new LifecycleElement(method);
                currInitMethods.add(element);
            }
            // 收集 destroy 类型注解标记的方法,至初销毁方法集合中
            if (method.isAnnotationPresent(this.destroyAnnotationType)) {
                currDestroyMethods.add(new LifecycleElement(method));
            }
        });

        initMethods.addAll(0, currInitMethods);
        destroyMethods.addAll(currDestroyMethods);
        targetClass = targetClass.getSuperclass();
        // 遍历目标 clazz 的父类,重复上述收集过程
    } while (targetClass != null && targetClass != Object.class);

    return (initMethods.isEmpty() && destroyMethods.isEmpty() ? this.emptyLifecycleMetadata :
            new LifecycleMetadata(clazz, initMethods, destroyMethods));
}

这里的 initAnnotationType 和 destroyAnnotationType 都有些啥呢?

  • initAnnotationType 中存的是 javax.annotation.PostConstruct 注解类;
  • destroyAnnotationType 中存的是 javax.annotation.PreDestroy 注解类;

我们看 InitDestroyAnnotationBeanPostProcessor 的构造;

// --------------------------- InitDestroyAnnotationBeanPostProcessor -----------------------
public class InitDestroyAnnotationBeanPostProcessor {
    @Nullable
    private Class<? extends Annotation> initAnnotationType;

    @Nullable
    private Class<? extends Annotation> destroyAnnotationType;
}


// --------------------------- CommonAnnotationBeanPostProcessor -----------------------
public class CommonAnnotationBeanPostProcessor extends InitDestroyAnnotationBeanPostProcessor {
    public CommonAnnotationBeanPostProcessor() {
        setOrder(Ordered.LOWEST_PRECEDENCE - 3);
        // 将 @PostConstruct、@PreDestroy 注解添加到 InitDestroyAnnotationBeanPostProcessor 对应属性中
        setInitAnnotationType(PostConstruct.class);
        setDestroyAnnotationType(PreDestroy.class);
    }
}

至此,@PostConstruct 注解解析执行完成;

  • 5
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值