Spring源码解读--(单例Bean初始化过程、BeanPostProcessor/InitializingBean/Aware接口的加载顺序)

前置说明:

   一、类与接口继承关系: public abstract class AbstractAutowireCapableBeanFactory

                                                           extends AbstractBeanFactory implements AutowireCapableBeanFactory

 二、本文章说明的是单例、并且是第一次实例化,同时不涉及其他复杂情况产生Bean用以说明Spring产生一个简单Bean单例的过程。用以说明在Bean实例化过程中对BeanPostProcessor/InitializingBean/Aware接口的调用顺序

      1、通过beanName获取Bean

           类AbstractBeanFactory的方法:  doGetBean(String name, @Nullable Class<T> requiredType,

                                                                         @Nullable Object[] args, boolean typeCheckOnly);

        如果类还没有创建并且是单例、类创建的实现:

                if(mbd.isSingleton()) {
                    sharedInstance = this.getSingleton(beanName, () -> {
                        try {
                            return this.createBean(beanName, mbd, args);
                        } catch (BeansException var5) {
                            this.destroySingleton(beanName);
                            throw var5;
                        }
                    });
                    bean = this.getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                }

     mbd即为RootBeanDefinition实现的是BeanDefinition接口,BeanDefinition接口对应的就是在spring配置文件配置的Bean

   即:

<bean id="car" name="car1" class="com.fev.Car"></bean>

this.getSingleton方法的知识点有单例三层缓存解决循环依赖,以及Lambda表达式,为了本文说明知识点的单一,暂时不展开说明,可搜索其他博文。

直接进入this.createBean(beanName, mbd, args)方法,就进入类AbstractAutowireCapableBeanFactory

  在此方法调用真正实例化bean的方法-this.doCreateBean(beanName, mbdToUse, args);

Bean实例化一个空对象的代码为

      BeanWrapper instanceWrapper = null;

        if(instanceWrapper == null) {
            instanceWrapper = this.createBeanInstance(beanName, mbd, args);
        }

        Object bean = instanceWrapper.getWrappedInstance();

  这些代码就是将(beanName, mbd, args)这些参数构建一个BeanWrapper .并产生一个空的Bean对象

                       

   之后就是通过方法this.populateBean(beanName, mbd, instanceWrapper)填充Bean的属性

  debug运行此方法前

                           

  运行此方法后:

                        

之后进入方法this.initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd);此方法为BeanPostProcessor/InitializingBean/Aware这三个接口的具体调用顺序:

  源码:

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
        if(System.getSecurityManager() != null) {
            AccessController.doPrivileged(() -> {
                this.invokeAwareMethods(beanName, bean);
                return null;
            }, this.getAccessControlContext());
        } else {
            this.invokeAwareMethods(beanName, bean);
        }

        Object wrappedBean = bean;
        if(mbd == null || !mbd.isSynthetic()) {
            wrappedBean = this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);
        }

        try {
            this.invokeInitMethods(beanName, wrappedBean, mbd);
        } catch (Throwable var6) {
            throw new BeanCreationException(mbd != null?mbd.getResourceDescription():null, beanName, "Invocation of init method failed", var6);
        }

        if(mbd == null || !mbd.isSynthetic()) {
            wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }

        return wrappedBean;
    }

由此可见,首先是运行Aware接口的方法this.invokeAwareMethods(beanName, bean);

    之后通过方法 this.applyBeanPostProcessorsBeforeInitialization(bean, beanName);运行BeanPostProcessor的postProcessBeforeInitialization方法

源码: 

public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException {
        Object result = existingBean;

        Object current;
        for(Iterator var4 = this.getBeanPostProcessors().iterator(); var4.hasNext(); result = current) {
            BeanPostProcessor processor = (BeanPostProcessor)var4.next();
            current = processor.postProcessBeforeInitialization(result, beanName);
            if(current == null) {
                return result;
            }
        }

        return result;
    }

然后运行方法this.invokeInitMethods(beanName, wrappedBean, mbd);执行InitializingBean接口的afterPropertiesSet方法.

源码:

 boolean isInitializingBean = bean instanceof InitializingBean;
        if(isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
            if(this.logger.isTraceEnabled()) {
                this.logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
            }

            if(System.getSecurityManager() != null) {
                try {
                    AccessController.doPrivileged(() -> {
                        ((InitializingBean)bean).afterPropertiesSet();
                        return null;
                    }, this.getAccessControlContext());
                } catch (PrivilegedActionException var6) {
                    throw var6.getException();
                }
            } else {
                ((InitializingBean)bean).afterPropertiesSet();
            }
        }

最后通过方法wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);

运行BeanPostProcessor接口的postProcessAfterInitialization(result, beanName)方法。

由此可见,这三个接口的调用顺序是Aware接口->BeanPostProcessor接口的postProcessBeforeInitialization方法->InitializingBean接口的afterPropertiesSet方法->BeanPostProcessor接口的postProcessAfterInitialization方法。

     最后提一下的是:由BeanPostProcessor、InitializingBean接口的使用也可以知道,BeanPostProcessor接口是对你注入的所有Bean都有作用,而InitializingBea。Aware是对你实现了这个接口的Bean起作用

猜你喜欢

转载自blog.csdn.net/qq_25179481/article/details/89204826