天天看點

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對象

Spring源碼解讀--(單例Bean初始化過程、BeanPostProcessor/InitializingBean/Aware接口的加載順序)

   之後就是通過方法this.populateBean(beanName, mbd, instanceWrapper)填充Bean的屬性

  debug運作此方法前

Spring源碼解讀--(單例Bean初始化過程、BeanPostProcessor/InitializingBean/Aware接口的加載順序)

  運作此方法後:

Spring源碼解讀--(單例Bean初始化過程、BeanPostProcessor/InitializingBean/Aware接口的加載順序)

之後進入方法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起作用