Spring源码 - @Resource、@PostConstruct、@PreDestroy原理分析(CommonAnnotationBeanPostProcessor - 上)

心不动则不痛 提交于 2019-12-24 13:30:05

目录

一、初始化

CommonAnnotationBeanPostProcessor的静态代码块初始化

CommonAnnotationBeanPostProcessor的无参数构造初始化

二、生命周期和回调时机

1、实现了BeanFactoryAware

2、继承自InitDestroyAnnotationBeanPostProcessor

1)、实现了PriorityOrdered排序接口

2)、实现了MergedBeanDefinitionPostProcessor(生命周期检查阶段)

3)、实现了DestructionAwareBeanPostProcessor接口(生命周期销毁阶段)

3、实现了顶层接口BeanPostProcessor(生命周期初始化阶段)

 


    CommonAnnotationBeanPostProcessor处理@Resource、javax.xml.ws.WebServiceRef、javax.ejb.EJB类型;而父类InitDestroyAnnotationBeanPostProcessorinitAnnotationTypedestroyAnnotationType分别存储自定义init方法(@PostConstruct)和@PreDestroy的方法。

 

一、初始化

CommonAnnotationBeanPostProcessor的静态代码块初始化

static {
    try {
        @SuppressWarnings("unchecked")
        Class<? extends Annotation> clazz = (Class<? extends Annotation>)
                ClassUtils.forName("javax.xml.ws.WebServiceRef", CommonAnnotationBeanPostProcessor.class.getClassLoader());
        webServiceRefClass = clazz;
    } catch (ClassNotFoundException ex) {
        webServiceRefClass = null;
    }
    try {
        @SuppressWarnings("unchecked")
        Class<? extends Annotation> clazz = (Class<? extends Annotation>)
                ClassUtils.forName("javax.ejb.EJB", CommonAnnotationBeanPostProcessor.class.getClassLoader());
        ejbRefClass = clazz;
    } catch (ClassNotFoundException ex) {
        ejbRefClass = null;
    }

    resourceAnnotationTypes.add(Resource.class);
    if (webServiceRefClass != null) {
        resourceAnnotationTypes.add(webServiceRefClass);
    }
    if (ejbRefClass != null) {
        resourceAnnotationTypes.add(ejbRefClass);
    }
}

 

CommonAnnotationBeanPostProcessor的无参数构造初始化

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

 

二、生命周期和回调时机

先看一下CommonAnnotationBeanPostProcessor的层级结构,并且按照调用顺序进行分析

1、实现了BeanFactoryAware

    那么会回调设置BeanFactory

2、继承自InitDestroyAnnotationBeanPostProcessor

1)、实现了PriorityOrdered排序接口

    在无参数构造中设置了排序值,在ApplicationContextAwareProcessor之后。

2)、实现了MergedBeanDefinitionPostProcessor(生命周期检查阶段)

    那么在getBean时,第一次缓存中没有,在调用doCreateBean时第3步会对所有MergedBeanDefinitionPostProcessorpostProcessMergedBeanDefinition方法进行回调。调用时机,详见:SpringIoc源码(十七)- BeanFactory(六)- getBean(doCreateBean总览)#3、MergedBeanDefinitionPostProcessor回调

@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, 
    Class<?> beanType, String beanName) {
    // 父类处理@PostConstruct、@PreDestroy的生命周期相关(check、init、destory、has)
    super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);
    // 子类处理@Resource(javax.xml.ws.WebServiceRef和javax.ejb.EJB不考虑了)
    InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);
    metadata.checkConfigMembers(beanDefinition);
}

    父类和子类按照层级处理各自内部的注解,当然在postProcessMergedBeanDefinition方法中只是check阶段。

3)、实现了DestructionAwareBeanPostProcessor接口(生命周期销毁阶段)

    之前分析过在所有bean在getBean时,只要实现了DisposableBean接口,那么都会往Spring注销容器中添加适配模式的DisposableBeanAdapter对象。详细见SpringIoc源码(十七)- BeanFactory(六)- getBean(doCreateBean总览)#6、注册DisposableBean那么在Bean注销时则会调用所有DestructionAwareBeanPostProcessorpostProcessBeforeDestruction方法,执行生命阶段的销毁方法。

@Override
public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
    LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
    // 省略try catch部分的代码
    metadata.invokeDestroyMethods(bean, beanName);
}

 

3、实现了顶层接口BeanPostProcessor(生命周期初始化阶段)

    则执行时机是该Bean生命周期回调阶段,会回调postProcessBeforeInitialization方法。执行时机在check之后,在destory之前。知道了定义的注解@Resource的个的生命周期,并且按层进行处理。那么主要的就是看生命周期中都这么进行处理的。

@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
    // 省略try catch部分代码
    metadata.invokeInitMethods(bean, beanName);
    return bean;
}

    维护父类生命周期LifecycleMetadata定义的checkConfigMembers、invokeInitMethods、invokeDestroyMethods、hasDestroyMethods。维护子类InjectionMetadata定义的checkConfigMembers、inject、clear。

    知道了是按层对不同的注解进行处理,也知道注解定义了生命周期,并且知道了回调顺序、时机。并且都调用了findLifecycleMetadata方法和各种生命周期的方法,那么下面需要专门各自生命周期。

 

 

 

 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!