• 从BeanFactory源码看Bean的生命周期


    下图是我搜索“Spring Bean生命周期”找到的图片,来自文章——Spring Bean的生命周期

    img

    下面,我们从AbstractAutowireCapableBeanFactory的源码中来分析这张图的各个阶段到底是怎么执行的。BeanFactory的基本源码解读在Spring BeanFactory接口分析&源码解读这篇文章中,如果读本篇文章稍显吃力,可以先去看看上面那篇。

    我们所用到的BeanFactory,ApplicationContext基本都继承了AbstractAutowireCapableBeanFactory,它是一个具有自动装载能力的BeanFactory,它可以响应@Autowire注解,所以,单独分析这个类不是没用的,而且很有必要。

    同时,由于Spring的BeanFactory层次结构中大量的使用了模板模式,所以我们可能在这个类的父子类中跳入跳出。

    Bean生命周期简单描述#

    我们先不看那些繁杂的生命周期方法回调,只看核心的部分,也就是图中四个大的黄色块

    1. 根据BeanDefinition创建Bean,这个过程称为实例化
    2. 填充Bean的属性
    3. 这时,Bean已经创建完毕并可以投入使用,这时需要调用Bean的初始化方法(如果用户指定了的话),这个过程称为初始化
    4. Bean被销毁

    所以,可以将Bean的创建归纳为:

    1. 实例化
    2. 设置属性
    3. 初始化
    4. 销毁

    虽然上面我们把大部分的繁杂的生命周期Hook给屏蔽了,总结出了四个核心的过程,但是这些Hook给了Spring框架带来了无尽的灵活性,所以也是非常重要的。但它们太容易让人眼花了,所以在继续之前,我们有必要先介绍一下那些东西都是什么,是用来解决什么问题的。

    BeanPostProcessor接口#

    BeanPostProcessor接口有如下方法:

    public interface BeanPostProcessor {
    
    	@Nullable
    	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    		return bean;
    	}
    
    	@Nullable
    	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    		return bean;
    	}
    
    }
    

    从方法名上看,xxxxBeforeInitializationxxxAfterInitialization意思是在初始化阶段前后做一些事,它的参数中,有实际创建出来的Bean和Bean的名字,该方法默认情况下返回原始的bean,也可以返回该bean的某种代理,实际上AOP就是通过这个接口来实现bean代理的返回的。

    所以,BeanPostProcessor实际关心的是Bean的初始化阶段

    ConfigurableBeanFactory接口的addBeanPostProcessor方法可以向BeanFactory中注册BeanPostProcessor

    InstantiationAwareBeanPostProcessor#

    首先,它继承BeanPostProcessor,所以它是一个BeanPostProcessor。但是从名字来看,InstantiationAware表示它更关心对于Bean的实例化阶段的感知,而不是初始化阶段,它发生在初始化阶段前面

    它的方法如下:

    public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
    
    	@Nullable
    	default Object postProcessBeforeInstantiation(Class beanClass, String beanName) throws BeansException {
    		return null;
    	}
    
    	default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
    		return true;
    	}
    
    	@Nullable
    	default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
    			throws BeansException {
    
    		return null;
    	}
    
        // 省略一个过时方法...
    }
    

    首先,xxxBeforeInstantiationxxxAfterInstantiation是很容易和之前的两个搞混的,不过以Instantiation结尾代表着它们关心的是Bean实例化的前后,在实例化前,该方法同样允许返回一个代替该Bean的对象,不过这次由于Bean还没有实际创建出来,所以它的参数中没有Bean对象,而是该Bean的Class对象。而在实例化后,它允许返回一个布尔值来指定是否该对该Bean的属性进行设置(true设置,false跳过)。

    Aware生命周期感知接口#

    Aware接口里啥也没有,有方法的是它的子接口

    public interface Aware { }
    

    Aware被一个想要感知到框架中的某种信息的Bean实现,比如一个Bean可能对创建它的Bean工厂感兴趣,那么它可以实现这个接口:

    public interface BeanFactoryAware extends Aware {
    
    	void setBeanFactory(BeanFactory beanFactory) throws BeansException;
    
    }
    

    Bean工厂会在该Bean的初始化阶段检测该Bean是否实现了这个接口,如果实现了就调用它的setBeanFactory方法将工厂设置进去。

    请注意,Aware被Bean实现,作用于单个Bean,BeanPostProcessor被注册到Bean工厂中,作用于工厂中的每个Bean。

    实例化Bean&属性设置#

    这图里所描述的是,创建Bean时先从BeanDefinition开始,然后实例化Bean,在实例化前后,InstantiationAwareBeanPostProcessor会被调用。

    img

    下面从doGetBean方法开始(getBean方法实际调用的方法,它已经是AbstractBeanFactory中的方法了),看下面的代码需要注意,Spring中Bean的作用域可以分为Singleton、Prototype和其它,其中Singleton和Prototype是Spring框架原生支持的,其它作用域需要自行扩展,比如SpringWebMVC扩展了Session等作用域。所以你看下面的代码时也要在脑袋里把它们分成Singleton、Prototype和其它作用域,要不然你可能就被这很长很长的代码搞迷糊了:

    protected  T doGetBean(
            String name, @Nullable Class requiredType, @Nullable Object[] args, boolean typeCheckOnly)
            throws BeansException {
    
        String beanName = transformedBeanName(name);
        Object beanInstance;
        // ...
    
            try {
                // 根据BeanName获取BeanDefinition
                // MergedBeanDefinition是将它和它的祖先Bean整合,这里可以先忽略,就当作普通的BeanDefinition
                RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                checkMergedBeanDefinition(mbd, beanName, args);
    
                // 如果是Singleton,按Singleton的方法创建
                if (mbd.isSingleton()) {
                    sharedInstance = getSingleton(beanName, () -> {
                        try {
                            // [+] 实际创建Bean
                            return createBean(beanName, mbd, args);
                        }
                        catch (BeansException ex) {}
                    });
                    beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                }
                // 如果是Prototype,按Prototype的方法创建
                else if (mbd.isPrototype()) {
                    Object prototypeInstance = null;
                    try {
                        beforePrototypeCreation(beanName);
                        // [+] 实际创建Bean
                        prototypeInstance = createBean(beanName, mbd, args);
                    }
                    finally {
                        afterPrototypeCreation(beanName);
                    }
                    beanInstance = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
                }
                // 如果是其它作用域,那么就放到其它作用域中创建
                // 这里的逻辑和Singleton很像,在Singleton创建中
                // Bean放到SingletonBeanRegistry中管理,而这个
                // 放到对应的作用域中管理
                else {
                    String scopeName = mbd.getScope();
                    Scope scope = this.scopes.get(scopeName);
                    try {
                        Object scopedInstance = scope.get(beanName, () -> {
                            beforePrototypeCreation(beanName);
                            try {
                                // [+] 实际创建Bean
                                return createBean(beanName, mbd, args);
                            }
                            finally {
                                afterPrototypeCreation(beanName);
                            }
                        });
                        beanInstance = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                    }
                    catch (IllegalStateException ex) {}
                }
            }
            catch (BeansException ex) {}
        }
    
        return adaptBeanInstance(name, beanInstance, requiredType);
    }
    

    所以,不管是哪个作用域,它们都调用了createBean来创建Bean,AbstractBeanFactory中并没有实现这个方法,createBeanAbstractAutowireCapableBeanFactory抽象类实现的:

    @Override
    protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
            throws BeanCreationException {
    
        RootBeanDefinition mbdToUse = mbd;
    
        try {
            // 在Bean实例化之前,让一些关心实例化阶段的BeanPostProcessor得到执行
            Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
            // 如果返回的bean不是null,那么结束整个阶段,直接返回这个值作为bean
            if (bean != null) {
                return bean;
            }
        }
        catch (Throwable ex) {}
    
        try {
            // 实例化Bean
            Object beanInstance = doCreateBean(beanName, mbdToUse, args);
            return beanInstance;
        }
        catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {}
    
        catch (Throwable ex) {}
    }
    

    所以,resolveBeforeInstantiation方法应该就是查找那些InstantiationAwareBeanPostProcessor,然后调用它们。

    InstantiationAwareBeanPostProcessor的before hook#

    protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
        Object bean = null;
        if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
            if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
                Class targetType = determineTargetType(beanName, mbd);
                if (targetType != null) {
                    // 应用BeanPostProcessor的beforeInstantiation
                    bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                    if (bean != null) {
                        // 调用BeanPostProcessors的初始化后方法,注意是初始化后不是实例化后
                        // 前提是before方法返回了一个对象
                        bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                    }
                }
            }
            mbd.beforeInstantiationResolved = (bean != null);
        }
        return bean;
    }
    

    我们可以看到,这个方法的代码非常简单,虽然还没写明,但是99%就是调用所有的InstantiationAwareBeanPostProcessor了,两个apply应该就是做这个工作的。我们不妨点进去看一个:

    @Nullable
    protected Object applyBeanPostProcessorsBeforeInstantiation(Class beanClass, String beanName) {
        for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
            Object result = bp.postProcessBeforeInstantiation(beanClass, beanName);
            if (result != null) {
                return result;
            }
        }
        return null;
    }
    

    这不就是对所有的InstantiationAwareBeanPostProcessor进行遍历调用吗,取第一个返回结果的Processor的结果。大家说,这里用到了什么设计模式?

    InstantiationAwareBeanPostProcessor before hook的使用#

    下面,我们自己创建一个实现类,它的功能就是打印所有进来的Bean名字和类型:

    public class MyInstantiationProcessor implements InstantiationAwareBeanPostProcessor {
        @Override
        public Object postProcessBeforeInstantiation(Class beanClass, String beanName) throws BeansException {
            System.out.println("[+] > MyInstantiationProcessor before bean instantiation : " + beanName + " => " + beanClass.getName());
            return null;
        }
    }
    

    下面,我们把它设置到BeanFactory中,然后尝试获取Bean:

    factory.addBeanPostProcessor(new MyInstantiationProcessor());
    Workbench workbench = factory.getBean(Workbench.class);
    System.out.println(workbench);
    

    输出:

    [+] > MyInstantiationProcessor before bean instantiation : workbench => top.yudoge.springserials.basic.beanfactory.beans.Workbench
    [+] > MyInstantiationProcessor before bean instantiation : person => top.yudoge.springserials.basic.beanfactory.beans.Person
    Workbench(operator=Person(name=Yudoge))
    

    因为Workbench对象依赖Person对象,所以引起了两个对象的连锁创建,最后一行我们得到了Workbench对象。

    下面我们尝试让BeanPostProcessor针对Person类返回一个另外的Bean,而不是null

    public class MyInstantiationProcessor implements InstantiationAwareBeanPostProcessor {
        @Override
        public Object postProcessBeforeInstantiation(Class beanClass, String beanName) throws BeansException {
            System.out.println("[+] > MyInstantiationProcessor before bean instantiation : " + beanName + " => " + beanClass.getName());
    
            if (beanClass.getName().equals(Person.class.getName())) {
                return new Person("我是MyInstantiationProcessor返回的Person");
            }
            return null;
        }
    }
    

    运行:

    [+] > MyInstantiationProcessor before bean instantiation : workbench => top.yudoge.springserials.basic.beanfactory.beans.Workbench
    [+] > MyInstantiationProcessor before bean instantiation : person => top.yudoge.springserials.basic.beanfactory.beans.Person
    Workbench(operator=Person(name=我是MyInstantiationProcessor返回的Person))
    

    成功的返回了我们创建出来的Person。

    对目前的InstantiationAwareBeanPostProcessor的before阶段做一个总结:

    1. BeanFactory会在创建Bean之前调用所有这种Processor的before方法
    2. 如果在before中返回了一个对象,那么这个对象就会代替原来的Bean,并且该bean的初始化后(不是实例化后)方法会被立即调用
    3. 否则,就是before中返回null,这时进入正常的Bean创建流程

    这个总结只是AbstractAutowireCapableBeanFactory中的实现方式,是否有其它BeanFactory以其它方式实现,暂不明确

    实际实例化Bean#

    所以,当InstantiationAwareBeanPostProcessor没有返回一个替代对象时,进入正常的Bean创建流程,开始实例化Bean。

    回到AbstractAutowireBeanFactorycreateBean方法:

    @Override
    protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
            throws BeanCreationException {
    
        RootBeanDefinition mbdToUse = mbd;
    
        try {
            Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
            if (bean != null) {
                return bean;
            }
        }
        catch (Throwable ex) { }
    
        try {
            // 创建Bean
            Object beanInstance = doCreateBean(beanName, mbdToUse, args);
            return beanInstance;
        }
        catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
            throw ex;
        }
        catch (Throwable ex) {}
    }
    
    

    这个doCreateBean方法就是用来实际实例化Bean的:

    protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
            throws BeanCreationException {
    
        BeanWrapper instanceWrapper = null;
        // 如果是Singleton,从缓存中拿原来的Bean
        if (mbd.isSingleton()) {
            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
        }
        if (instanceWrapper == null) {
            // 实例化Bean
            instanceWrapper = createBeanInstance(beanName, mbd, args);
        }
        // 从BeanWrapper中拿出实际的Bean对象
        Object bean = instanceWrapper.getWrappedInstance();
    
        // ...
    }
    

    向populateBean方法中试探——InstantiationAwareBeanPostProcessor的after方法#

    doCreateBean方法里有这样两行:

    populateBean(beanName, mbd, instanceWrapper);
    exposedObject = initializeBean(beanName, exposedObject, mbd);
    

    很明显,它们代表了Bean生命周期的属性设置阶段和初始化阶段,但是到目前为止,我们还没有看到InstantiationAwareBeanPostProcessor的除了before以外的另两个方法被调用。虽然populateBean方法名看起来就是设置Bean属性了,但我们也只能往下看,没准InstantiationAwareBeanPostProcessor的另外两个方法在这个populateBean设置属性之前被调用了呢?

    protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
        // 调用所有InstantiationAwareBeanPostProcessor的BeanPostProcessor
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
                if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                    return;
                }
            }
        }
    
        // ...
    }
    

    我日尼玛,果然啊!!!进来就开始调用InstantiationAwareBeanPostProcessor的after方法

    所以,做个小总结:

    1. 对于那些InstantiationAwareBeanPostProcessor没有拦截(before实例化方法返回null的)的Bean,InstantiationAwareBeanPostProcessor的after实例化方法也会被调用
    2. 而对于那些before实例化方法没有返回null的,这个after实例化方法不会走,直接调用了after初始化方法,也就是说把实例化到初始化中间的过程都跳过了

    InstantiationAwareBeanPostProcessor的postProcessProperties方法#

    protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
        // 调用after实例化方法
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
                if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                    return;
                }
            }
        }
    
        // 获取所有属性
        PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
    
        // 自动注入,自动注入是针对pvs的,而不是bean本身
        int resolvedAutowireMode = mbd.getResolvedAutowireMode();
        if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
            MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
            // Add property values based on autowire by name if applicable.
            if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
                autowireByName(beanName, mbd, bw, newPvs);
            }
            // Add property values based on autowire by type if applicable.
            if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
                autowireByType(beanName, mbd, bw, newPvs);
            }
            pvs = newPvs;
        }
    
        // 对于所有的InstantiationAwareBeanPostProcessor,调用它们的属性设置方法
        boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
        boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
    
        PropertyDescriptor[] filteredPds = null;
        if (hasInstAwareBpps) {
            if (pvs == null) {
                pvs = mbd.getPropertyValues();
            }
            // 对于所有InstantiationAwareBeanPostProcessor,调用它的postProcessProperties方法
            for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
                PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
                // 如果该方法返回的新pvs为null,那么再调用postProcessPropertyValues
                if (pvsToUse == null) {
                    // 该方法默认返回初始pvs
                    pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                    if (pvsToUse == null) {
                        return;
                    }
                }
                // 让pvs等于两次BeanProcessor方法调用后返回的pvs
                pvs = pvsToUse;
            }
        }
    
        // 实际设置Bean属性
        if (pvs != null) {
            applyPropertyValues(beanName, mbd, bw, pvs);
        }
    }
    

    在这里,我们可以看到,BeanFactory并没有实际设置属性,而是先用一个pvs数据结构来保存所有待设置的属性,自动注入时也操作的是pvs。这给了InstantiationAwareBeanPostProcessor可以对属性值进行二次修改的能力。

    InstantiationAwareBeanPostProcessor的两个与属性相关的方法都可以返回新的pvs,你可以对原始pvs进行改动。而postProcessProperties方法默认返回null,就是不改动,postProcessPropertyValues方法默认返回原始pvs,也是不改动。

    稍后,BeanFactory会把pvs应用到Bean中。

    postProcessProperties方法的实战#

    这里,我们检测如果pvs中有名为operator的属性要设置,我们就创建一个新的pvs,并覆盖它的operator属性,并返回它,否则我们返回null,也就是不覆盖属性:

    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        if (pvs.contains("operator")) {
            MutablePropertyValues clonedPvs = new MutablePropertyValues(pvs);
            clonedPvs.addPropertyValue("operator", new Person("修改了pvs之后的person"));
            return clonedPvs;
        }
        return null;
    }
    

    结果,由于autowire阶段Person已经被创建了,所以结果中person的实例化阶段也被打印了:

    [+] > MyInstantiationProcessor before bean instantiation : workbench => top.yudoge.springserials.basic.beanfactory.beans.Workbench
    [+] > MyInstantiationProcessor before bean instantiation : person => top.yudoge.springserials.basic.beanfactory.beans.Person
    Workbench(operator=Person(name=修改了pvs之后的person))
    

    由于我不了解直接修改原始pvs会不会有副作用,所以我选择了克隆一个对象

    这两个阶段最后的总结#

    回到这个图上

    img

    1. 从BeanDefinition创建实例化Bean
    2. 实例化之前如果有InstantiationAwareBeanPostProcessor,调用before实例化方法
    3. 如果并没有一个实例化BeanPostProcessor接管Bean创建,那么进入正常实例化阶段
    4. 实例化Bean
    5. 调用InstantiationAwareBeanPostProcessor的after实例化方法
    6. 对pvs进行设置
    7. 调用InstantiationAwareBeanPostProcessor的postProcessProperties方法对pvs进行修改
    8. 实际的Bean属性设置

    初始化阶段#

    看起来挺复杂的,其实很简单:

    img

    主要分为几个阶段:

    1. Aware接口的回调
    2. BeanPostProcessor的before初始化回调
    3. 各种初始化方法的回调
    4. BeanPostProcessor的after初始化回调

    所以,初始化阶段其实没做任何实际的事,只是对各种生命周期方法和Bean感知方法进行回调,通知它们Bean已经初始化了。或者也可以理解为,初始化阶段做的最主要的工作就是调用Bean的aware感知方法和初始化方法

    // doCreateBean
    // 属性设置阶段
    populateBean(beanName, mbd, instanceWrapper);
    // 初始化阶段
    exposedObject = initializeBean(beanName, exposedObject, mbd);
    

    进入initalizeBean,可以看到里面的代码正对应着图中的每一步:

    protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    
        // 调用感知方法
        invokeAwareMethods(beanName, bean);
    
        // 调用BeanPostProcessor的before初始化方法
        Object wrappedBean = bean;
        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
        }
    
        // 调用自定义初始化方法
        try {
            invokeInitMethods(beanName, wrappedBean, mbd);
        }
    
        // 调用BeanPostProcessor的after初始化方法
        catch (Throwable ex) {}
        if (mbd == null || !mbd.isSynthetic()) {
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }
    
        return wrappedBean;
    }
    

    Aware感知方法的调用#

    进入invokeAwareMethod方法,里面对BeanNameAwareBeanClassLoaderAwareBeanFactoryAware做了检测,并调用了对应的设置方法:

    private void invokeAwareMethods(String beanName, Object bean) {
        if (bean instanceof Aware) {
            if (bean instanceof BeanNameAware) {
                ((BeanNameAware) bean).setBeanName(beanName);
            }
            if (bean instanceof BeanClassLoaderAware) {
                ClassLoader bcl = getBeanClassLoader();
                if (bcl != null) {
                    ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
                }
            }
            if (bean instanceof BeanFactoryAware) {
                ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
            }
        }
    }
    

    对于BeanFactory,它只支持这些Aware,ApplicationContext会支持更多的Aware。

    Aware感知方法的实战#

    Workbench类实现BeanFactoryAware接口并打印出创建它的BeanFactory:

    @Data
    public class Workbench implements BeanFactoryAware {
        @Autowired
        private Person operator;
    
        @Override
        public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
            System.out.println("BeanFactory => " + beanFactory);
        }
    }
    

    img

    需要注意的是,一旦你的Bean实现了某个Aware接口,就证明它要感知到某些框架中的东西,这会让它直接与框架产生耦合。

    BeanPostProcessor before初始化的调用#

    这里和之前的套路一样,并且before方法可以返回一个包装过的Bean做为代理(默认不包装,这时wrappedBean==bean)

    	protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    
            invokeAwareMethods(beanName, bean);
    
            // 进行before初始化调用
    		Object wrappedBean = bean;
    		if (mbd == null || !mbd.isSynthetic()) {
    			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    		}
    
        // ...
    }
    

    遍历每个BeanPostProcessor,调用before初始化方法:

    @Override
    public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
            throws BeansException {
    
        Object result = existingBean;
        for (BeanPostProcessor processor : getBeanPostProcessors()) {
            Object current = processor.postProcessBeforeInitialization(result, beanName);
            if (current == null) {
                return result;
            }
            result = current;
        }
        return result;
    }
    

    没啥好解释的,实际上InstantiationAwareBeanPostProcessor的过程和它差不多,并且比它复杂。

    init-method的调用#

    // 调用before初始化
    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }
    
    try {
        // 调用init-method
        invokeInitMethods(beanName, wrappedBean, mbd);
    }
    catch (Throwable ex) {
        throw new BeanCreationException(
                (mbd != null ? mbd.getResourceDescription() : null),
                beanName, "Invocation of init method failed", ex);
    }
    

    那么我们来查看invokeInitMethods方法:

    protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
            throws Throwable {
    
        // 该Bean是否是initializingBean的实例
        boolean isInitializingBean = (bean instanceof InitializingBean);
        // 如果是,并且有`afterPropertiesSet`方法
        if (isInitializingBean && (mbd == null || !mbd.hasAnyExternallyManagedInitMethod("afterPropertiesSet"))) {
            // 调用afterPropertiesSet方法
            ((InitializingBean) bean).afterPropertiesSet();
        }
    
        if (mbd != null && bean.getClass() != NullBean.class) {
            // 获取init-method名字
            String initMethodName = mbd.getInitMethodName();
            // 如果`initMethodName`不是空并且`initMethodName`并不和`afterPropertiesSet`同名且不是InitalizingBean(防止重复调用),并且Bean中实际有这个方法
            if (StringUtils.hasLength(initMethodName) &&
                    !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
                    !mbd.hasAnyExternallyManagedInitMethod(initMethodName)) {
                // 调用initmethod
                invokeCustomInitMethod(beanName, bean, mbd);
            }
        }
    }
    

    所以,BeanFactory先是对于实现了InitializingBean的Bean的afterPropertiesSet进行调用,然后再对用户指定的init-method进行调用。

    InitializingBean实战#

    @Data
    public class Workbench implements InitializingBean {
        @Autowired
        private Person operator;
    
        @Override
        public void afterPropertiesSet() throws Exception {
            System.out.println("afterPropertiesSet");
        }
    }
    

    结果:

    afterPropertiesSet
    Workbench(operator=Person(name=Yudoge))
    

    init-method实战#

    添加init方法

    @Data
    public class Workbench implements InitializingBean {
        @Autowired
        private Person operator;
    
        @Override
        public void afterPropertiesSet() throws Exception {
            System.out.println("afterPropertiesSet");
        }
    
        public void init() {
            System.out.println("init");
        }
    }
    

    BeanDefinition中设置init方法名

    // 设置Init方法名
    workbenchRbd.setInitMethodName("init");
    

    结果

    afterPropertiesSet
    init
    Workbench(operator=Person(name=Yudoge))
    

    关于@PostConstruct#

    貌似BeanFactory并不支持@PostConstruct,它好像是ApplicationContext通过预注册InstantiationAwareBeanPostProcessor实现的。这是我猜的。

    BeanPostProcessor.post初始化#

    略,因为前面已经讲了够多了,猜也能猜到怎么实现的

    初始化阶段总结#

    1. 调用Aware方法
    2. 调用BeanPostProcessor的before初始化
    3. 如果是InitializingBean,调用afterPropertiesSet方法
    4. 如果有init-method,调用
    5. 调用BeanPostProcessor的after初始化

    尾声:Bean的销毁阶段#

    img

    回到doCreateBean方法中,最后,该方法判断了,如果必要的话就将该Bean注册到DisposableBean中:

    try {
        registerDisposableBeanIfNecessary(beanName, bean, mbd);
    }
    catch (BeanDefinitionValidationException ex) {}
    

    我猜其中的逻辑就是看看该Bean是不是DisposableBean的实例,如果是,注册到一个什么表中,方便销毁Bean时调用它的destory方法。

    我们先不管,先看BeanFactory中有没有什么destroyBean这种方法。果然,在ConfigurableBeanFactory中定义了这个方法,AbstractBeanFactory把它实现了:

    @Override
    public void destroyBean(String beanName, Object beanInstance) {
        destroyBean(beanName, beanInstance, getMergedLocalBeanDefinition(beanName));
    }
    
    protected void destroyBean(String beanName, Object bean, RootBeanDefinition mbd) {
        new DisposableBeanAdapter(
                bean, beanName, mbd, getBeanPostProcessorCache().destructionAware, getAccessControlContext()).destroy();
    }
    

    这里创建了一个什么DisposableBeanAdapter,然后调用了destroy方法,就没干别的了。

    DisposableBeanAdapter#

    DisposableBeanAdapter的描述如下:

    /**
     * 实现了`DisposableBean`和`Runnable`的Adapter,对给定的Bean执行多个销毁步骤:
     * 
     *  - DestructionAwareBeanPostProcessors;
     *  - 本身就实现了DisposableBean的Bean
     *  - BeanDefinition中定义的Bean销毁方法
     */
    class DisposableBeanAdapter implements DisposableBean, Runnable, Serializable 
    

    所以,看起来,整个Bean的销毁步骤都是这哥们儿一个人完成的喽。

    img

    不过这个图应该画错了,它把DestructionAwareBeanPostProcessors写成了InstantiationAwareBeanPostProcessor

    看看它被调用的构造方法里写了啥:

    public DisposableBeanAdapter(Object bean, String beanName, RootBeanDefinition beanDefinition,
            List postProcessors, @Nullable AccessControlContext acc) {
    
        this.bean = bean;
        this.beanName = beanName;
        this.nonPublicAccessAllowed = beanDefinition.isNonPublicAccessAllowed();
        // 该Bean是不是可调用的DisposableBean
        this.invokeDisposableBean = (bean instanceof DisposableBean &&
                !beanDefinition.hasAnyExternallyManagedDestroyMethod(DESTROY_METHOD_NAME));
        
        // destroy方法名
        String destroyMethodName = inferDestroyMethodIfNecessary(bean, beanDefinition);
    
        // 和初始化哪里一样,防止destroy方法名和DisposableBean的方法名一样,重复调用
        if (destroyMethodName != null &&
                !(this.invokeDisposableBean && DESTROY_METHOD_NAME.equals(destroyMethodName)) &&
                !beanDefinition.hasAnyExternallyManagedDestroyMethod(destroyMethodName)) {
            // 如果Bean是一个AutoClosable并且自定义的销毁方法名也是close的话
            this.invokeAutoCloseable = (bean instanceof AutoCloseable && CLOSE_METHOD_NAME.equals(destroyMethodName));
    
            if (!this.invokeAutoCloseable) {
                // 如果不是,destroyMethodName就使用用户指定的并解析对应方法
                this.destroyMethodName = destroyMethodName;
                Method destroyMethod = determineDestroyMethod(destroyMethodName);
                // 省略一些destroy method参数设置相关的代码
                this.destroyMethod = destroyMethod;
            }
        }
        // 获取beanPostProcessors(filterPostProcessors会过滤掉所有非DestructionAwareBeanPostProcessor的类)
        this.beanPostProcessors = filterPostProcessors(postProcessors, bean);
        this.acc = acc;
    }
    

    这里就是做了一些初始化工作,把需要的成员变量都解析出来,方便后面destroy时使用。

    然后我们看看destroy方法:

    public void destroy() {
        // 调用所有DestructionAwareBeanPostProcessor的postProcessBeforeDestruction
        if (!CollectionUtils.isEmpty(this.beanPostProcessors)) {
            for (DestructionAwareBeanPostProcessor processor : this.beanPostProcessors) {
                processor.postProcessBeforeDestruction(this.bean, this.beanName);
            }
        }
    
        // 如果是一个disposableBean,调用它的destroy
        if (this.invokeDisposableBean) {
            ((DisposableBean) this.bean).destroy();
        }
    
        // 如果是AutoCloseable(并且自定义销毁方法名也是close),直接调用close
        if (this.invokeAutoCloseable) {
            ((AutoCloseable) this.bean).close();
        }
        // 否则去调用自定义方法
        else if (this.destroyMethod != null) {
            invokeCustomDestroyMethod(this.destroyMethod);
        }
        // 有可能存在destroyMethod没解析,但是destroyMethodName有了的情况,解析并调用
        else if (this.destroyMethodName != null) {
            Method destroyMethod = determineDestroyMethod(this.destroyMethodName);
            if (destroyMethod != null) {
                invokeCustomDestroyMethod(ClassUtils.getInterfaceMethodIfPossible(destroyMethod, this.bean.getClass()));
            }
        }
    }
    

    实战DestructionAwareBeanPostProcessor#

    创建DestructionAwareBeanPostProcessor

    public class MyDestructionProcessor implements DestructionAwareBeanPostProcessor {
        @Override
        public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
            System.out.println("[+] DestructionProcessor : " + beanName);
        }
    }
    

    向工厂中添加BeanPostProcessor,并销毁Bean:

    factory.addBeanPostProcessor(new MyDestructionProcessor());
    factory.destroyBean("workbench", workbench);
    

    结果:

    Workbench(operator=Person(name=Yudoge))
    [+] DestructionProcessor : top.yudoge.springserials.basic.beanfactory.beans.Workbench
    

    实战DisposableBean#

    让Bean实现DisposableBean

    @Data
    public class Workbench implements DisposableBean {
        @Autowired
        private Person operator;
    
        @Override
        public void destroy() throws Exception {
            System.out.println("DisposableBean destroy");
        }
    }
    

    结果:

    Workbench(operator=Person(name=Yudoge))
    [+] DestructionProcessor : top.yudoge.springserials.basic.beanfactory.beans.Workbench
    DisposableBean destroy
    

    实战CustomDestroyMethod#

    添加自定义销毁方法

    @Data
    public class Workbench implements DisposableBean {
        @Autowired
        private Person operator;
    
        @Override
        public void destroy() throws Exception {
            System.out.println("DisposableBean destroy");
        }
    
        public void customDestroyMethod() {
            System.out.println("Custom destroy method...");
        }
    }
    

    在BeanDefinition中定义:

    workbenchRbd.setDestroyMethodName("customDestroyMethod");
    

    结果:

    Workbench(operator=Person(name=Yudoge))
    [+] DestructionProcessor : workbench
    DisposableBean destroy
    Custom destroy method...
    

    总结#

    现在,Bean销毁阶段的逻辑已经全部理解完毕

    img

    1. 调用DestructionAwareBeanPostProcessor的before销毁方法
    2. 如果实现了DisposableBean,调用它的Destroy方法
    3. 调用自定义destroy-method方法
    4. 说明:真正意义上的销毁(从容器中移除bean)是在AbstractApplicationContext.close方法中实现的,在此方法中不仅会将bean从容器中移除,还会调用到我们实现的这些回调相关的方法。

    最后的总结#

    1. 从BeanDefinition获取Bean信息
    2. 调用InstantiationAwareBeanPostProcessor的before实例化方法
    3. 如果它返回一个对象,那么直接进入该对象的初始化后方法
    4. 否则,它返回null,进入正常的Bean生命周期
    5. 实例化Bean
    6. 调用populateBean,该方法的目的是对Bean属性进行设置
    7. 调用InstantiationAwareBeanPostProcessor的after实例化方法,该方法的返回值决定是否跳过属性设置阶段
    8. 解析该Bean的pvs,自动注入该pvs
    9. 调用InstantiationAwareBeanPostProcessor中两个和属性设置有关的方法,允许它们对属性进行动态修改
    10. 调用initializingBean进入初始化阶段
    11. 检测Bean实现了哪些Aware接口,调用它们
    12. 调用所有BeanPostProcessor的before初始化方法,该方法可以返回Bean的一个代理
    13. 如果Bean是InitializingBean,调用它的afterPropertiesSet方法
    14. 如果Bean设置了启动方法,调用启动方法
    15. 调用所有BeanPostProcessor的after初始化方法,该方法可以返回Bean的一个代理
    16. 调用destroyBean进入Bean销毁阶段
    17. 创建DisposableBeanAdapter,它负责对Bean的销毁进行生命周期方法的调用
    18. 调用所有DestructionAwareBeanPostProcessor的before销毁方法
    19. 如果是DisposableBean,调用destroy方法
    20. 如果设置了destroy-method,调用它
    参考原文链接:https://www.cnblogs.com/lilpig/p/16477006.html

    __EOF__

  • 本文作者: DiligentCoder
  • 本文链接: https://www.cnblogs.com/LoveShare/p/16856070.html
  • 关于博主: 评论和私信会在第一时间回复。或者直接私信我。
  • 版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
  • 声援博主: 如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。
  • 相关阅读:
    [论文翻译]Classical Probabilistic Models and Conditional Random Fields(下)
    Linux(11)动静态库生成与安装
    java8使用stream流将list转map
    尚硅谷大数据项目《在线教育之离线数仓》笔记007
    【配电网重构】基于yalmip求解含sop+二阶锥配电网重构附matlab代码
    模板进阶:非类型模板参数,特化
    Python之网络编程
    Delphi 开发过程中简单的版本管理与回退(2)
    局域网监控软件如何防止数据泄密
    力扣刷题 day14:10-14
  • 原文地址:https://www.cnblogs.com/LoveShare/p/16856070.html