SpringBoot源码解读与原理分析(二十四)IOC容器的刷新(五)

文章目录

    • 7.11 初始化所有剩下的单实例bean对象
      • 7.11.1 beanFactory.preInstantiateSingletons
      • 7.11.2 getBean
        • 7.11.2.1 别名的解析处理
        • 7.11.2.2 判断是否已注册过
        • 7.11.2.3 创建前的检查
        • 7.11.2.4 标记准备创建的bean对象
        • 7.11.2.5 合并BeanDefinition
        • 7.11.2.6 bean对象的创建
        • 7.11.2.7 getSingleton控制单实例对象
      • 7.11.3 createBean
        • 7.11.3.1 resolveBeforeInstantiation
        • 7.11.3.2 doCreateBean
          • 1.实例化bean对象
            • (1)解析bean对象的类型
            • (2)处理Supplier创建和工厂方法创建
            • (3)原型Bean的创建优化
            • (4)实例化bean对象的真实动作
          • 2.属性赋值前的注解信息收集
            • (1)InitDestroyAnnotationBeanPostProcessor
            • (2)CommonAnnotationBeanPostProcessor
            • (3)AutowiredAnnotationBeanPostProcessor
          • 3.早期bean对象引用的获取与缓存
          • 4.属性赋值和依赖注入
            • (1)回调InstantiationAwareBeanPostProcessor
            • (2)再次回调InstantiationAwareBeanPostProcessor
            • (3)属性赋值
          • 5.bean对象的初始化
            • (1)invokeAwareMethods——执行Aware类型接口的回调
            • (2)applyBeanPostProcessorsBeforeInitialization——执行BeanPostProcessor的前置回调
            • (3)invokeInitMethods——执行初始化生命周期回调
            • (4)applyBeanPostProcessorsAfterInitialization——执行BeanPostProcessor的后置回调
          • 6.注册销毁时的回调
      • 7.11.4 SmartInitializingSingleton

前面四节,详细梳理了IOC容器刷新的前面十步(7.1-7.10)以及一个重要的后置处理器ConfigurationClassPostProcessor,详见:

SpringBoot源码解读与原理分析(二十)IOC容器的刷新(一)
SpringBoot源码解读与原理分析(二十一)IOC容器的刷新(二)
SpringBoot源码解读与原理分析(二十二)IOC容器的刷新(三)ConfigurationClassPostProcessor
SpringBoot源码解读与原理分析(二十三)IOC容器的刷新(四)

这一节继续梳理第十一步(7.11)。

本文超长预警,有1400+行。

代码清单1AbstractApplicationContext.java

public void refresh() throws BeansException, IllegalStateException {
    synchronized (this.startupShutdownMonitor) {
        // Prepare this context for refreshing.
        // 7.1 初始化前的预处理
        prepareRefresh();

        // Tell the subclass to refresh the internal bean factory.
        // 7.2 获取BeanFactory,加载所有bean的定义信息(未实例化)
        ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

        // Prepare the bean factory for use in this context.
        // 7.3 BeanFactory的预处理配置
        prepareBeanFactory(beanFactory);

        try {
            // Allows post-processing of the bean factory in context subclasses.
            // 7.4 BeanFactory准备工作完成后的后置处理
            postProcessBeanFactory(beanFactory);

            // Invoke factory processors registered as beans in the context.
            // 7.5 BeanFactory创建后的后置处理器的执行
            invokeBeanFactoryPostProcessors(beanFactory);

            // Register bean processors that intercept bean creation.
            // 7.6 初始化Bean的后置处理器
            registerBeanPostProcessors(beanFactory);

            // Initialize message source for this context.
            // 7.7 初始化MessageSource
            initMessageSource();

            // Initialize event multicaster for this context.
            // 7.8 初始化事件广播器
            initApplicationEventMulticaster();

            // Initialize other special beans in specific context subclasses.
            // 7.9 子类扩展的刷新动作
            onRefresh();

            // Check for listener beans and register them.
            // 7.10 注册监听器
            registerListeners();

            // 至此,BeanFactory创建完成

            // Instantiate all remaining (non-lazy-init) singletons.
            // 7.11 初始化所有剩下的单实例bean对象
            finishBeanFactoryInitialization(beanFactory);

            // Last step: publish corresponding event.
            // 7.12 完成容器的创建工作
            finishRefresh();
        } catch (BeansException ex) {
            if (logger.isWarnEnabled()) {
                logger.warn("Exception encountered during context initialization - " +
                        "cancelling refresh attempt: " + ex);
            }

            // Destroy already created singletons to avoid dangling resources.
            destroyBeans();

            // Reset 'active' flag.
            cancelRefresh(ex);

            // Propagate exception to caller.
            throw ex;
        } finally {
            // Reset common introspection caches in Spring's core, since we
            // might not ever need metadata for singleton beans anymore...
            // 7.13 清理缓存
            resetCommonCaches();
        }
    }
}

7.11 初始化所有剩下的单实例bean对象

// 7.11 初始化所有剩下的单实例bean对象
finishBeanFactoryInitialization(beanFactory);
代码清单2AbstractApplicationContext.java

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
    // 初始化类型转换器ConversionService
    if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
            beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
        beanFactory.setConversionService(
                beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
    }

    // 注册嵌入式值解析器EmbeddedValueResolver
    if (!beanFactory.hasEmbeddedValueResolver()) {
        beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
    }

    // 初始化LoadTimeWeaverAware
    String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
    for (String weaverAwareName : weaverAwareNames) {
        getBean(weaverAwareName);
    }
    beanFactory.setTempClassLoader(null);

    // 冻结配置
    beanFactory.freezeConfiguration();

    // 实例化所有非延迟加载的单实例Bean
    beanFactory.preInstantiateSingletons();
}

由 代码清单2 可知,finishBeanFactoryInitialization方法前面的逻辑都是预备性的,其逻辑重点在最后一行beanFactory.preInstantiateSingletons实例化所有非延迟加载的单实例Bean

7.11.1 beanFactory.preInstantiateSingletons

借助IDEA得知,preInstantiateSingletons方法在ConfigurableListableBeanFactory中定义,最终实现在DefaultListableBeanFactory中。

代码清单3DefaultListableBeanFactory.java

@Override
public void preInstantiateSingletons() throws BeansException {
    // logger...

    List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
    for (String beanName : beanNames) {
        // 先合并BeanDefinition
        RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
        // 不是抽象的、不是延迟加载的单实例Bean需要初始化
        if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
            if (isFactoryBean(beanName)) {
                Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                // 如果是FactoryBean默认不立即初始化
                if (bean instanceof FactoryBean) {
                    // FactoryBean的处理逻辑
                }
            } else {
                // 普通的Bean的初始化
                getBean(beanName);
            }
        }
    }

    // ...
}

由 代码清单3 可知,在初始化所有非延迟加载的单实例bean对象时,会根据bean对象的类型分别处理。如果bean对象的类型是FactoryBean,会有单独的处理逻辑;而初始化普通bean对象时,使用的是getBean方法。

7.11.2 getBean

代码清单4AbstractBeanFactory.java

@Override
public Object getBean(String name) throws BeansException {
    return doGetBean(name, null, null, false);
}

由 代码清单4 可知,getBean方法会转调doGetBean方法。doGetBean方法的逻辑复杂,下面拆解来看。

7.11.2.1 别名的解析处理
代码清单5AbstractBeanFactory.java

protected <T> T doGetBean(
    String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
    throws BeansException {

    // 别名的解析处理
    String beanName = transformedBeanName(name);

    // ···
}

protected String transformedBeanName(String name) {
    return canonicalName(BeanFactoryUtils.transformedBeanName(name));
}

public String canonicalName(String name) {
    String canonicalName = name;
    // Handle aliasing...
    String resolvedName;
    do {
        // 从别名集合中提取真实的名称
        resolvedName = this.aliasMap.get(canonicalName);
        if (resolvedName != null) {
            canonicalName = resolvedName;
        }
    }
    while (resolvedName != null);
    return canonicalName;
}

在使用@Bean注解标注在方法上注册bean对象时,可以通过设置其name或value属性为bean对象指定名称。而name或value属性可以传入一个数组,意味着一个bean对象可以有多个名称,默认情况下传入的第一个属性值是bean对象的名称,其余的都是别名。

代码清单5 的逻辑就是处理这些别名:如果参数name是一个别名,则通过transformedBeanName方法转换为真正的名称。

7.11.2.2 判断是否已注册过
代码清单6AbstractBeanFactory.java

protected <T> T doGetBean(
    String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
    throws BeansException {
        // ···
        // 先尝试从已经实例化好的Bean中找有没有当前Bean
        // 如果能找到,说明Bean已经被实例化了,直接返回
        Object sharedInstance = getSingleton(beanName);
        if (sharedInstance != null && args == null) {
            // logger ......
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        } else
        // ···
}

protected Object getObjectForBeanInstance(
        Object beanInstance, String name, String beanName, @Nullable RootBeanDefinition mbd) {

    // ...
    // 如果不是FactoryBean,直接返回
    if (!(beanInstance instanceof FactoryBean)) {
        return beanInstance;
    }

    // ...
    // 如果是FactoryBean,则调用getObject方法获取对象
    object = getObjectFromFactoryBean(factory, beanName, !synthetic);
    
    return object;
}     
}

由 代码清单6 可知,第二步是尝试获取IOC容器中是否已创建并缓存当前正在获取的单实例bean对象,如果成功获取到,说明Bean已经被实例化了,直接返回。getObjectForBeanInstance方法对返回的结果进行分类处理,如果获取到的bean对象是一个FactoryBean,则进行一些额外处理,并通过调用getObject方法获取对象;如果是普通的bean对象,则直接返回。

7.11.2.3 创建前的检查

如果 代码清单6 中没有获取到bean对象,说明当前处理的Bean还未创建,即if逻辑判断为false,则进入else结构部分,开始创建该bean对象。

代码清单7AbstractBeanFactory.java

protected <T> T doGetBean(
    String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
    throws BeansException {
        // ···
        else {
            // 如果当前创建的bean对象是一个原型Bean并且正在创建,抛出异常
            if (isPrototypeCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
            }

            BeanFactory parentBeanFactory = getParentBeanFactory();
            // 如果当前BeanFactory没有当前bean对象的BeanDefinition
            // 则通过父级BeanFactory返回
            if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
                // Not found -> check parent.
                String nameToLookup = originalBeanName(name);
                if (parentBeanFactory instanceof AbstractBeanFactory) {
                    return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                            nameToLookup, requiredType, args, typeCheckOnly);
                } else if (args != null) {
                    // Delegation to parent with explicit args.
                    return (T) parentBeanFactory.getBean(nameToLookup, args);
                } else if (requiredType != null) {
                    // No args -> delegate to standard getBean method.
                    return parentBeanFactory.getBean(nameToLookup, requiredType);
                } else {
                    return (T) parentBeanFactory.getBean(nameToLookup);
                }
            }
        }
        // ···
}

由 代码清单7 可知,创建bean对象之前会进行校验,判断当前要创建的bean对象是否是一个原型Bean并且已经在创建了,如果是,说明当前原型Bean在一次获取中将产生两个对象,这种现象不合理,所以会抛出异常。

第二项校验是判断当前BeanFactory是否包含当前bean对象的BeanDefinition,如果没有,则通过父级BeanFactory的doGetBean方法或getBean方法返回(BeanFactory的层次性的体现)。

7.11.2.4 标记准备创建的bean对象
代码清单8AbstractBeanFactory.java

protected <T> T doGetBean(
    String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
    throws BeansException {
        // ···
        else {
            // ...
            if (!typeCheckOnly) {
                markBeanAsCreated(beanName);
            }
            // ...
        }
        // ···
}

protected void markBeanAsCreated(String beanName) {
    if (!this.alreadyCreated.contains(beanName)) {
        synchronized (this.mergedBeanDefinitions) {
            if (!this.alreadyCreated.contains(beanName)) {
                clearMergedBeanDefinition(beanName);
                this.alreadyCreated.add(beanName);
            }
        }
    }
}

由 代码清单8 可知,在确认Bean确需创建之后,会对其名称进行标记。markBeanAsCreated方法会将当前正在处理的bean对象的名称放入alreadyCreated集合中,代表该bean对象已被创建

7.11.2.5 合并BeanDefinition
代码清单9AbstractBeanFactory.java

protected <T> T doGetBean(
    String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
    throws BeansException {
        // ···
        else {
            // ...
            try {
                // 合并BeanDefinition
                RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                checkMergedBeanDefinition(mbd, beanName, args);

                // 处理当前bean对象的依赖(@DependsOn注解)
                String[] dependsOn = mbd.getDependsOn();
                if (dependsOn != null) {
                    for (String dep : dependsOn) {
                        // 注册并初始化依赖的bean对象
                        registerDependentBean(dep, beanName);
                        try {
                            getBean(dep);
                        } // catch ...
                        }
                    }
                }
                // ...
            } // catch...
        }
        // ···
}

由 代码清单9 可知,合并BeanDefinition的getMergedLocalBeanDefinition方法可以得到当前正在创建的bean对象需要依赖哪些bean对象,也就是在当前创建的bean对象中显式标注了@DependsOn注解的属性

由于标注了@DependsOn注解的属性代表强制依赖,IOC容器会优先处理这些被强制依赖的bean对象并将其初始化,而初始化的方式依然是getBean方法。

7.11.2.6 bean对象的创建
代码清单10AbstractBeanFactory.java

protected <T> T doGetBean(
    String name, @Nullable Class<T> requiredType, @Nullable Object[] args, boolean typeCheckOnly)
    throws BeansException {
        // ···
        else {
            // ...
            try {
                // ...
                // 单实例singleton作用域
                if (mbd.isSingleton()) {
                    // 每次调用createBean返回的都是同一个实例
                    sharedInstance = getSingleton(beanName, () -> {
                        try {
                            return createBean(beanName, mbd, args);
                        } // catch...
                    });
                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                } 
                // 原型prototype作用域
                else if (mbd.isPrototype()) {
                    // 每次调用createBean都会创建一个新的实例
                    Object prototypeInstance = null;
                    try {
                        beforePrototypeCreation(beanName);
                        prototypeInstance = createBean(beanName, mbd, args);
                    } finally {
                        afterPrototypeCreation(beanName);
                    }
                    bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
                } 
                // 其他作用域
                else {
                    String scopeName = mbd.getScope();
                    // ...
                    try {
                        Object scopedInstance = scope.get(beanName, () -> {
                            beforePrototypeCreation(beanName);
                            try {
                                return createBean(beanName, mbd, args);
                            } finally {
                                afterPrototypeCreation(beanName);
                            }
                        });
                        bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                    } // catch...
                }
            } // catch...
        }
        // ···
}

由 代码清单10 可知,经过多步的检查和前置处理之后,bean对象终于开始创建。IOC容器会根据当前正在创建的bean对象的作用域(单实例singleton作用域、原型prototype作用域或其他)决定如何创建对象

但不管是哪些作用域,底层都是调用createBean方法创建对象。不同的是,对于单实例singleton作用域,每次调用createBean方法返回的都是同一个实例;对于原型prototype作用域,每次调用createBean方法都会创建一个新的实例

IOC容器中控制单实例对象的方式是使用getSingleton方法配合ObjectFactory实现的。

7.11.2.7 getSingleton控制单实例对象
代码清单11DefaultSingletonBeanRegistry.java

private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
    Assert.notNull(beanName, "Bean name must not be null");
    synchronized (this.singletonObjects) {
        // 加锁后,从缓存集合中提取bean对象实例
        Object singletonObject = this.singletonObjects.get(beanName);
        if (singletonObject == null) {
            // 如果缓存中没有,则创建对象
            if (this.singletonsCurrentlyInDestruction) {
                // throw ...
            }
            if (logger.isDebugEnabled()) {
                // logger ...
            }
            beforeSingletonCreation(beanName);
            boolean newSingleton = false;
            boolean recordSuppressedExceptions = (this.suppressedExceptions == null);
            if (recordSuppressedExceptions) {
                this.suppressedExceptions = new LinkedHashSet<>();
            }
            try {
                // 调用getObject方法就是外层调用createBean方法
                singletonObject = singletonFactory.getObject();
                newSingleton = true;
            } // catch finally...
            
            // 新创建的单实例bean对象存入缓存中
            if (newSingleton) {
                addSingleton(beanName, singletonObject);
            }
        }
        return singletonObject;
    }
}

由 代码清单11 可知,控制单实例bean对象的方式借助一个名为singletonObjects的Map集合充当缓存区,在获取单实例bean对象时,会先从缓存区中尝试获取,如果没有获取到则会调用createBean方法创建对象,并保存到singletonObjects缓存中。

简言之,单实例bean对象在第一次创建时会调用createBean方法真正地创建对象,创建完毕会存入IOC容器底层的singletonObjects缓存区,后续再次获取时会直接从缓存区中取出bean对象并返回。

7.11.3 createBean

代码清单12AbstractAutowireCapableBeanFactory.java

protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
        throws BeanCreationException {

    // logger ...
    }
    RootBeanDefinition mbdToUse = mbd;

    // 根据BeanDefinition获取当前正在创建的bean对象的类型
    Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
    if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
        mbdToUse = new RootBeanDefinition(mbd);
        mbdToUse.setBeanClass(resolvedClass);
    }

    // ...

    try {
        // 后置处理器BeanPostProcessors拦截创建bean对象
        Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
        if (bean != null) {
            return bean;
        }
    } // catch ...

    try {
        // 真正创建bean对象
        Object beanInstance = doCreateBean(beanName, mbdToUse, args);
        if (logger.isTraceEnabled()) {
            logger.trace("Finished creating instance of bean '" + beanName + "'");
        }
        return beanInstance;
    } // catch ...
}

由 代码清单12 可知,实际创建bean对象有两个切入点:

  • 通过resolveBeforeInstantiation方法创建bean对象:由方法名可以理解为“实例化之前的处理”,因此这只是创建bean对象之前的拦截。
  • 通过doCreateBean方法实际创建bean对象。
7.11.3.1 resolveBeforeInstantiation
代码清单13AbstractAutowireCapableBeanFactory.java

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
    Object bean = null;
    if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
        // Make sure bean class is actually resolved at this point.
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            Class<?> targetType = determineTargetType(beanName, mbd);
            if (targetType != null) {
                // 执行所有InstantiationAwareBeanPostProcessor
                bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                if (bean != null) {
                    // 如果成功创建了bean对象,则执行所有的BeanPostProcessors
                    bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                }
            }
        }
        mbd.beforeInstantiationResolved = (bean != null);
    }
    return bean;
}

protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
    // 循环找出所有的InstantiationAwareBeanPostProcessor
    for (BeanPostProcessor bp : getBeanPostProcessors()) {
        if (bp instanceof InstantiationAwareBeanPostProcessor) {
            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
            // 调用其postProcessBeforeInstantiation方法实例化对象
            Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
            if (result != null) {
                return result;
            }
        }
    }
    return null;
}

@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
        throws BeansException {

    Object result = existingBean;
    // 循环找出所有的BeanPostProcessor
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        // 调用其postProcessAfterInitialization方法增强对象
        Object current = processor.postProcessAfterInitialization(result, beanName);
        if (current == null) {
            return result;
        }
        result = current;
    }
    return result;
}

由 代码清单14 可知,拦截bean对象的创建行为有两步:先执行所有InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法创建对象,如果成功创建bean对象,在执行所有BeanPostProcessors的postProcessAfterInitialization方法增强对象

以上两个后置处理器的底层逻辑基本一致,都是从IOC容器获取到所有注册的后置处理器,并逐一回调。

7.11.3.2 doCreateBean

如果resolveBeforeInstantiation方法没有创建出bean对象,则需要执行doCreateBean方法创建bean对象的实例。doCreateBean方法的逻辑非常长,下面拆解来看。

1.实例化bean对象
代码清单14AbstractAutowireCapableBeanFactory.java

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
        throws BeanCreationException {

    // ...
    if (instanceWrapper == null) {
        // 创建bean对象实例
        instanceWrapper = createBeanInstance(beanName, mbd, args);
    }
    // 得到bean对象的引用
    Object bean = instanceWrapper.getWrappedInstance();
    Class<?> beanType = instanceWrapper.getWrappedClass();
    if (beanType != NullBean.class) {
        mbd.resolvedTargetType = beanType;
    }
    // ...
}

由 代码清单14 可知,实例化bean对象是创建对象的第一步,即createBeanInstance方法。

(1)解析bean对象的类型
代码清单15AbstractAutowireCapableBeanFactory.java

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    // 解析出bean对象的类型
    Class<?> beanClass = resolveBeanClass(mbd, beanName);
    // 如果bean对象无法被访问,则抛出异常
    if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
        throw new BeanCreationException(mbd.getResourceDescription(), beanName,
            "Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
    }
    // ...
}

由 代码清单15 可知,createBeanInstance方法首先会检验当前要创建的bean对象所属类型是否可以被正常访问,如果不可以,则会抛出异常。

(2)处理Supplier创建和工厂方法创建
代码清单16AbstractAutowireCapableBeanFactory.java

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    // ...
    //如果制定了实例Supplier,则通过Supplier实例化bean对象
    Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
    if (instanceSupplier != null) {
        return obtainFromSupplier(instanceSupplier, beanName);
    }
    // 如果指定了工厂方法,则通过工厂方法实例化bean对象
    if (mbd.getFactoryMethodName() != null) {
        return instantiateUsingFactoryMethod(beanName, mbd, args);
    }
    // ...
}

/**
 * Obtain a bean instance from the given supplier.
 */
protected BeanWrapper obtainFromSupplier(Supplier<?> instanceSupplier, String beanName) {

由 代码清单16 可知,如果BeanDefinition中指定了实例Supplier,则通过Supplier实例化bean对象。obtainFromSupplier方法的 javadoc 指出,这个方法可以从给定的Supplier中得到bean实例。

如果BeanDefinition中指定了工厂方法,则通过工厂方法实例化bean对象。

(3)原型Bean的创建优化
代码清单17AbstractAutowireCapableBeanFactory.java

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    // ...
    boolean resolved = false;
    boolean autowireNecessary = false;
    if (args == null) {
        synchronized (mbd.constructorArgumentLock) {
            if (mbd.resolvedConstructorOrFactoryMethod != null) {
                resolved = true;
                autowireNecessary = mbd.constructorArgumentsResolved;
            }
        }
    }
    if (resolved) {
        if (autowireNecessary) {
            // 直接从BeanDefinition中取出构造方法以实例化对象
            return autowireConstructor(beanName, mbd, null, null);
        }
        else {
            // 通过构造方法实例化对象
            return instantiateBean(beanName, mbd);
        }
    }
    // ...
}

由 代码清单17 可知,这一段代码是针对原型Bean而言的,在第一次原型bean对象创建完成后,将创建过程中引用的构造方法缓存到BeanDefinition中,以备后续创建时可以直接取出。

(4)实例化bean对象的真实动作
代码清单18AbstractAutowireCapableBeanFactory.java

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    // ...
    // 回调SmartInstantiationAwareBeanPostProcessor寻找构造方法
    Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
    // 条件1:通过SmartInstantiationAwareBeanPostProcessor找到了构造方法
    // 条件2:配置自动注入方式为AUTOWIRE_CONSTRUCTOR
    // 条件3:使用XML配置文件的方式定义Bean时指定了constructor-arg标签
    // 条件4:调用getBean方法获取bean对象时传入了args参数
    if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
        mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
        // 使用显式构造方法实例化bean对象
        return autowireConstructor(beanName, mbd, ctors, args);
    }
    // 如果BeanDefinition中指定了首选构造函数,也使用显式构造方法实例化bean对象
    ctors = mbd.getPreferredConstructors();
    if (ctors != null) {
        return autowireConstructor(beanName, mbd, ctors, null);
    }
    
    // 使用无参数构造方法实例化bean对象
    return instantiateBean(beanName, mbd);
}

由 代码清单18 可知,当触发一些条件时,IOC容器会选择使用显式构造方法实例化bean对象。

  • 条件1:通过SmartInstantiationAwareBeanPostProcessor找到了构造方法;
  • 条件2:配置自动注入方式为AUTOWIRE_CONSTRUCTOR;
  • 条件3:使用XML配置文件的方式定义Bean时指定了constructor-arg标签;
  • 条件4:调用getBean方法获取bean对象时传入了args参数;
  • 条件5:BeanDefinition中指定了首选构造函数。

如果以上条件都不满足,则会使用默认的无参构造方法创建对象。

代码清单19AbstractAutowireCapableBeanFactory.java

protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) {
    try {
        Object beanInstance;
        // 借助InstantiationStrategy实例化对象
        if (System.getSecurityManager() != null) {
            beanInstance = AccessController.doPrivileged(
                    (PrivilegedAction<Object>) () -> getInstantiationStrategy().instantiate(mbd, beanName, this),
                    getAccessControlContext());
        } else {
            beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, this);
        }
        BeanWrapper bw = new BeanWrapperImpl(beanInstance);
        initBeanWrapper(bw);
        return bw;
    } // catch ...
}

@Override
public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
    // ...
    return BeanUtils.instantiateClass(constructorToUse);
}

由 代码清单19 可知,instantiateBean的重点在于获取InstantiationStrategy,使用BeanUtils.instantiateClass方法反射实例化bean对象。

经过createBeanInstance方法后,即可得到一个对象内部没有任何额外注入的bean对象,bean对象的实例化完毕。

2.属性赋值前的注解信息收集

回到doCreateBean方法,实例化bean对象之后,进入属性赋值前的注解信息收集。

代码清单20AbstractAutowireCapableBeanFactory.java

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
        throws BeanCreationException {

    // ...
    synchronized (mbd.postProcessingLock) {
        if (!mbd.postProcessed) {
            try {
                applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
            } // catch ...
            mbd.postProcessed = true;
        }
    }
    // ...
}

protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
    for (BeanPostProcessor bp : getBeanPostProcessors()) {
        if (bp instanceof MergedBeanDefinitionPostProcessor) {
            MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
            bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
        }
    }
}

由 代码清单20 可知,核心方法applyMergedBeanDefinitionPostProcessors会回调所有的MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition方法。借助IDEA可知,有几个重要的后置处理器实现了该方法。

(1)InitDestroyAnnotationBeanPostProcessor
代码清单21InitDestroyAnnotationBeanPostProcessor.java

@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
    LifecycleMetadata metadata = findLifecycleMetadata(beanType);
    metadata.checkConfigMembers(beanDefinition);
}

private LifecycleMetadata findLifecycleMetadata(Class<?> clazz) {
    // ...
    return buildLifecycleMetadata(clazz);
}

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<>();
        // 反射所有的public方法
        ReflectionUtils.doWithLocalMethods(targetClass, method -> {
            // 寻找所有被@PostConstruct注解标注的方法
            if (this.initAnnotationType != null && method.isAnnotationPresent(this.initAnnotationType)) {
                LifecycleElement element = new LifecycleElement(method);
                currInitMethods.add(element);
                // logger ...
            }
            // 寻找所有被@PostDestroy注解标注的方法
            if (this.destroyAnnotationType != null && method.isAnnotationPresent(this.destroyAnnotationType)) {
                currDestroyMethods.add(new LifecycleElement(method));
                // logger ...
            }
        });

        initMethods.addAll(0, currInitMethods);
        destroyMethods.addAll(currDestroyMethods);
        // 依次向上寻找父类
        targetClass = targetClass.getSuperclass();
    }
    while (targetClass != null && targetClass != Object.class);

    // return ...
}

由 代码清单21 可知,postProcessMergedBeanDefinition方法会扫描和收集当前正在创建的bean对象中标注了@PostConstruct注解和@PostDestroy注解的方法。源码中的initAnnotationType对应@PostConstruct注解,destroyAnnotationType对应@PostDestroy注解。

(2)CommonAnnotationBeanPostProcessor
代码清单22CommonAnnotationBeanPostProcessor.java

@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
    // 调用父类InitDestroyAnnotationBeanPostProcessor的postProcessMergedBeanDefinition方法
    super.postProcessMergedBeanDefinition(beanDefinition, beanType, beanName);
    InjectionMetadata metadata = findResourceMetadata(beanName, beanType, null);
    metadata.checkConfigMembers(beanDefinition);
}

private InjectionMetadata findResourceMetadata(String beanName, final Class<?> clazz, @Nullable PropertyValues pvs) {
    // ...
    metadata = buildResourceMetadata(clazz);
    // ...
}

private InjectionMetadata buildResourceMetadata(final Class<?> clazz) {
    // ...

    do {
        final List<InjectionMetadata.InjectedElement> currElements = new ArrayList<>();

        ReflectionUtils.doWithLocalFields(targetClass, field -> {
            // @WebServiceRef
            if (webServiceRefClass != null && field.isAnnotationPresent(webServiceRefClass)) {
                if (Modifier.isStatic(field.getModifiers())) {
                    throw new IllegalStateException("@WebServiceRef annotation is not supported on static fields");
                }
                currElements.add(new WebServiceRefElement(field, field, null));
            } 
            // @EJB
            else if (ejbClass != null && field.isAnnotationPresent(ejbClass)) {
                if (Modifier.isStatic(field.getModifiers())) {
                    throw new IllegalStateException("@EJB annotation is not supported on static fields");
                }
                currElements.add(new EjbRefElement(field, field, null));
            } 
            // @Resource
            else if (field.isAnnotationPresent(Resource.class)) {
                if (Modifier.isStatic(field.getModifiers())) {
                    throw new IllegalStateException("@Resource annotation is not supported on static fields");
                }
                if (!this.ignoredResourceTypes.contains(field.getType().getName())) {
                    currElements.add(new ResourceElement(field, field, null));
                }
            }
        });

        // ...

        elements.addAll(0, currElements);
        // 依次向上寻找父类
        targetClass = targetClass.getSuperclass();
    }
    while (targetClass != null && targetClass != Object.class);

    return InjectionMetadata.forElements(elements, clazz);
}

由 代码清单22 可知,CommonAnnotationBeanPostProcessor的父类是InitDestroyAnnotationBeanPostProcessor,所以它也具备收集@PostConstruct注解和@PostDestroy注解的能力,同时还具备收集JSR-250规范中的注解(如@WebServiceRef、@EJB、 @Resource)的能力。

(3)AutowiredAnnotationBeanPostProcessor
代码清单23AutowiredAnnotationBeanPostProcessor.java

public AutowiredAnnotationBeanPostProcessor() {
    this.autowiredAnnotationTypes.add(Autowired.class);
    this.autowiredAnnotationTypes.add(Value.class);
    try {
        this.autowiredAnnotationTypes.add((Class<? extends Annotation>)
        ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
        logger.trace("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");
    } // catch ...
}

@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
    InjectionMetadata metadata = findAutowiringMetadata(beanName, beanType, null);
    metadata.checkConfigMembers(beanDefinition);
}

由 代码清单24 可知,AutowiredAnnotationBeanPostProcessor具备的能力是收集@Autowired、@Value、@Inject注解,收集原理和前面两者后置处理器的原理一致。

3.早期bean对象引用的获取与缓存

回到doCreateBean方法,收集完属性赋值前的注解信息之后,开始收集早期bean对象引用。

代码清单25AbstractAutowireCapableBeanFactory.java

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
        throws BeanCreationException {

    // ...
    boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
            isSingletonCurrentlyInCreation(beanName));
    if (earlySingletonExposure) {
        if (logger.isTraceEnabled()) {
            logger.trace("Eagerly caching bean '" + beanName +
                "' to allow for resolving potential circular references");
        }
        // 处理循环依赖的问题
        addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
    }
    // ...
}

由 代码清单25 可知,bean对象实例化之后,虽然没有进行属性赋值和依赖注入,但也已经是一个实实在在的对象。如果在此期间有另外的bean对象需要依赖它,就不应该再创建一个新的bean对象,而是直接获取当前bean对象的引用即可。

这个设计就是为了解决bean对象之间的循环依赖。

4.属性赋值和依赖注入

回到doCreateBean方法,处理早期bean对象引用之后,开始进行属性赋值和依赖注入。

代码清单26AbstractAutowireCapableBeanFactory.java

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
        throws BeanCreationException {

    // ...
    // Initialize the bean instance.
    Object exposedObject = bean;
    try {
        // 属性赋值和依赖注入
        populateBean(beanName, mbd, instanceWrapper);
        // bean对象的初始化
        exposedObject = initializeBean(beanName, exposedObject, mbd);
    } // catch ...
    
    // ...
}
(1)回调InstantiationAwareBeanPostProcessor
代码清单27AbstractAutowireCapableBeanFactory.java

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
    // 前置检查 ...
    
    // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
    // state of the bean before properties are set. This can be used, for example,
    // to support styles of field injection.
    // 在设置属性之前,让任何InstantiationAwareBeanPostProcessors都有机会修改
    // Bean的状态,例如支持属性字段的注入。
    if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                    return;
                }
            }
        }
    }
    // ...

由 代码清单27 可知,InstantiationAwareBeanPostProcessors是一个可以干预Bean的属性、状态等信息的后置处理器。其postProcessAfterInstantiation方法的返回值是boolean类型,当返回false时直接结束populateBean方法,不再执行真正的属性赋值+组件依赖注入的逻辑。

这样设计的目的在于,允许开发者在bean对象已经实例化完毕但还没有开始属性赋值和依赖注入时切入自定义逻辑。

(2)再次回调InstantiationAwareBeanPostProcessor
代码清单28AbstractAutowireCapableBeanFactory.java

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
    // ...
    for (BeanPostProcessor bp : getBeanPostProcessors()) {
        if (bp instanceof InstantiationAwareBeanPostProcessor) {
            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
            PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
            // ...
        }
    }
    // ...

由 代码清单28 可知,populateBean方法会再一次回调InstantiationAwareBeanPostProcessor,但这次调用的是其postProcessProperties方法,作用是执行组件的依赖注入。

负责依赖注入的后置处理器是前面提到的AutowiredAnnotationBeanPostProcessor。

代码清单29AutowiredAnnotationBeanPostProcessor.java

@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
    InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
    try {
        metadata.inject(bean, beanName, pvs);
    } // catch ...
}

public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
    Collection<InjectedElement> checkedElements = this.checkedElements;
    // 取出在前面收集的@Autowired、@Value、@Inject注解
    Collection<InjectedElement> elementsToIterate =
            (checkedElements != null ? checkedElements : this.injectedElements);
    if (!elementsToIterate.isEmpty()) {
        // 逐个注入
        for (InjectedElement element : elementsToIterate) {
            element.inject(target, beanName, pvs);
        }
    }
}

由 代码清单29 可知,在进行依赖注入时,首先会取出前面步骤收集的所有标注了@Autowired、@Value、@Inject注解的方法,封装为InjectionMetadata,并调用其inject方法进行依赖注入。

(3)属性赋值
代码清单30AbstractAutowireCapableBeanFactory.java

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
    // ...
    PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
    // ...
    if (needsDepCheck) {
        if (filteredPds == null) {
            filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
        }
        checkDependencies(beanName, mbd, filteredPds, pvs);
    }
    
    if (pvs != null) {
        // 应用PropertyValues对象到当前正在创建的bean对象
        applyPropertyValues(beanName, mbd, bw, pvs);
    }

由 代码清单30 可知,经过前面几个步骤之后,生成了一个PropertyValues对象,该对象封装了当前正在创建的bean对象中需要依赖的所有属性赋值类元素,最后执行的applyPropertyValues方法就是把前面准备好的PropertyValues对象封装的内容应用到当前正在创建的bean对象实例中。

applyPropertyValues方法内部,会将属性值反射注入bean对象的成员属性中。

经过该阶段,bean对象的属性赋值和依赖注入工作完成。

5.bean对象的初始化

由 代码清单26 可知,属性赋值和依赖注入完成后,立刻开始初始化bean对象,即initializeBean方法。

代码清单31AbstractAutowireCapableBeanFactory.java

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
    if (System.getSecurityManager() != null) {
        AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
            // 执行Aware类型接口的回调
            invokeAwareMethods(beanName, bean);
            return null;
        }, getAccessControlContext());
    } else {
        invokeAwareMethods(beanName, bean);
    }

    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
        // 执行BeanPostProcessor的前置回调
        wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }

    try {
        // 执行生命周期回调
        invokeInitMethods(beanName, wrappedBean, mbd);
    } // catch ...
    if (mbd == null || !mbd.isSynthetic()) {
        // 执行BeanPostProcessor的后置回调
        wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }

    return wrappedBean;
}

由 代码清单31 可知,initializeBean方法包含4个回调逻辑。

(1)invokeAwareMethods——执行Aware类型接口的回调
代码清单32AbstractAutowireCapableBeanFactory.java

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);
        }
    }
}

由 代码清单32 可知,invokeAwareMethods方法会判断当前bean对象是否实现了特定的Aware接口,如果实现了就强转后掉哟个对应的setter方法。

(2)applyBeanPostProcessorsBeforeInitialization——执行BeanPostProcessor的前置回调
代码清单33AbstractAutowireCapableBeanFactory.java

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

    Object result = existingBean;
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        Object current = processor.postProcessBeforeInitialization(result, beanName);
        // 如果一个BeanPostProcessor处理bean对象后返回的结果为null
        // 则不再执行剩余的BeanPostProcessor
        // 而直接返回上一个BeanPostProcessor处理之后的bean对象
        if (current == null) {
            return result;
        }
        result = current;
    }
    return result;
}

由 代码清单33 可知,该回调逻辑是执行BeanPostProcessor的postProcessBeforeInitialization方法。

在这中间有一个特殊的设计:如果一个BeanPostProcessor处理bean对象后返回的结果为null,则不再执行剩余的BeanPostProcessor,而直接返回上一个BeanPostProcessor处理之后的bean对象。这样设计的目的,是方便开发者在设计postProcessBeforeInitialization方法时,可以通过控制其返回值以进行特殊处理。

下面介绍两个后置处理器实现类。

  • InitDestroyAnnotationBeanPostProcessor
代码清单34InitDestroyAnnotationBeanPostProcessor.java

@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    // 收集标注了@PostConstruct和@PreDestroy的方法
    InitDestroyAnnotationBeanPostProcessor.LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
    try {
        // 执行初始化方法
        metadata.invokeInitMethods(bean, beanName);
    } // catch ...
    return bean;
}

public void invokeInitMethods(Object target, String beanName) throws Throwable {
    Collection<InitDestroyAnnotationBeanPostProcessor.LifecycleElement> checkedInitMethods = this.checkedInitMethods;
    Collection<InitDestroyAnnotationBeanPostProcessor.LifecycleElement> initMethodsToIterate =
            (checkedInitMethods != null ? checkedInitMethods : this.initMethods);
    if (!initMethodsToIterate.isEmpty()) {
        for (InitDestroyAnnotationBeanPostProcessor.LifecycleElement element : initMethodsToIterate) {
            // logger ...
            element.invoke(target);
        }
    }
}

public void invoke(Object target) throws Throwable {
    ReflectionUtils.makeAccessible(this.method);
    this.method.invoke(target, (Object[]) null);
}

由 代码清单34 可知,postProcessBeforeInitialization方法首先会收集标注了@PostConstruct和@PreDestroy的方法(收集方法详见【7.11.3.2 2.属性赋值前的注解信息收集 (1)InitDestroyAnnotationBeanPostProcessor】),然后回调bean对象中所有标注了@PostConstruct注解的方法。

ReflectionUtils.makeAccessible(this.method);可知,反射执行目标方法时会先借助ReflectionUtils获取其访问权,这意味着对于使用@PostConstruct注解标注的方法的访问修饰符没有强限制

this.method.invoke(target, (Object[]) null);可知,最终回调方法时传入的参数时空对象,这也解释了为什么在使用@PostConstruct注解标注方法时一定要设置为空参数方法

  • ApplicationContextAwareProcessor
代码清单35ApplicationContextAwareProcessor.java

@Override
@Nullable
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    // 不是这6个Aware子接口的,不予处理
    if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
            bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
            bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)){
        return bean;
    }

    // ...
    
    else {
        invokeAwareInterfaces(bean);
    }

    return bean;
}

private void invokeAwareInterfaces(Object bean) {
    if (bean instanceof EnvironmentAware) {
        ((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
    }
    if (bean instanceof EmbeddedValueResolverAware) {
        ((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
    }
    if (bean instanceof ResourceLoaderAware) {
        ((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
    }
    if (bean instanceof ApplicationEventPublisherAware) {
        ((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
    }
    if (bean instanceof MessageSourceAware) {
        ((MessageSourceAware) bean).setMessageSource(this.applicationContext);
    }
    if (bean instanceof ApplicationContextAware) {
        ((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
    }
}

由 代码清单35 可知,ApplicationContextAwareProcessor支持6个Aware子接口的回调注入,否则不予处理。执行Aware子接口时根据不同类型执行setter方法。

(3)invokeInitMethods——执行初始化生命周期回调
代码清单36AbstractAutowireCapableBeanFactory.java

protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
        throws Throwable {

    boolean isInitializingBean = (bean instanceof InitializingBean);
    if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
        // ...
        } else {
            // 回调InitializingBean的afterPropertiesSet方法
            ((InitializingBean) bean).afterPropertiesSet();
        }
    }

    if (mbd != null && bean.getClass() != NullBean.class) {
        String initMethodName = mbd.getInitMethodName();
        if (StringUtils.hasLength(initMethodName) &&
                !(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
                !mbd.isExternallyManagedInitMethod(initMethodName)) {
            // 反射回调init-method方法
            invokeCustomInitMethod(beanName, bean, mbd);
        }
    }
}

由 代码清单36 可知,初始化生命周期回调包括init-method方法和InitializingBean接口的初始化逻辑回调。

(4)applyBeanPostProcessorsAfterInitialization——执行BeanPostProcessor的后置回调
代码清单37AbstractAutowireCapableBeanFactory.java

@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
        throws BeansException {

    Object result = existingBean;
    for (BeanPostProcessor processor : getBeanPostProcessors()) {
        Object current = processor.postProcessAfterInitialization(result, beanName);
        if (current == null) {
            return result;
        }
        result = current;
    }
    return result;
}

由 代码清单37 可知,回调BeanPostProcessor的后置拦截的逻辑和前置拦截几乎一致。重点关注两个后置处理器的实现。

  • AbstractAutoProxyCreator

所有以AutoProxyCreator结尾的类都与AOP相关,且都是具备代理对象创建能力的后置处理器,可以在bean对象本身的初始化逻辑完成后根据需要创建代理对象。

  • ApplicationListenerDetector

ApplicationListenerDetector的作用是关联事件广播器和监听器的引用,因此在创建ApplicationListener类型的bean对象时,ApplicationListenerDetector会检测并将其添加到ApplicationContext中,关联ApplicationEventMulticaster事件广播器。

6.注册销毁时的回调

回到doCreateBean方法,bean对象初始化之后,最后一步是注册销毁时的回调。

代码清单38AbstractAutowireCapableBeanFactory.java

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
        throws BeanCreationException {

    // ...
    try {
        // 注册销毁时的回调
        registerDisposableBeanIfNecessary(beanName, bean, mbd);
    } // catch ...
    // ...
}

protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
    AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
    // 不是原型Bean,且定义了销毁类型的方法
    if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
        if (mbd.isSingleton()) {
            // 注册一个执行给定bean对象的所有销毁工作的DisposableBean实现:Destruction
            // 通过实现DisposableBean接口,或自定义销毁方法。
            registerDisposableBean(beanName,
                    new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
        } // else...
    }
}

由 代码清单38 可知,如果一个bean对象的所属类型实现了DisposableBean接口,或者内部方法中标注了@PreDestory注解,或者声明了destory-method方法,则会在doCreateBean方法的最后阶段注册一个销毁bean对象的回调钩子,在IOC容器关闭时,这部分bean对象会回调其自定义的自毁逻辑。

至此,doCreateBean方法执行完毕,一个bean对象被创建完成并返回。

7.11.4 SmartInitializingSingleton

回到preInstantiateSingletons方法,在bean对象创建完成后,还有一段额外的逻辑。

代码清单39DefaultListableBeanFactory.java

@Override
public void preInstantiateSingletons() throws BeansException {
    // ...

    for (String beanName : beanNames) {
        Object singletonInstance = getSingleton(beanName);
        if (singletonInstance instanceof SmartInitializingSingleton) {
            SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
            if (System.getSecurityManager() != null) {
                AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                    smartSingleton.afterSingletonsInstantiated();
                    return null;
                }, getAccessControlContext());
            }
            else {
                smartSingleton.afterSingletonsInstantiated();
            }
        }
    }
}

由 代码清单39 可知,如果bean对象实现了SmartInitializingSingleton接口,则遍历回调其afterSingletonsInstantiated方法。这实际上是在非延迟加载的单实例bean对象全部创建完成后提供一个统一的扩展回调时机,以便在ApplicationContext初始化完成之前处理一些特殊的逻辑。

经过上述一系列复杂逻辑后,finishBeanFactoryInitialization方法执行完毕,所有非延迟加载的单实例bean对象全部完成创建并初始化。

······

至此,IOC容器的刷新完成了前面十一步,分别是:

7.1 初始化前的预处理
7.2 初始化BeanFactory
7.3 BeanFactory的预处理配置
7.4 BeanFactory准备工作完成后的后置处理
7.5 BeanFactory创建后的后置处理器的执行
7.6 初始化Bean的后置处理器
7.7 初始化国际化组件
7.8 初始化事件广播器
7.9 子类扩展的刷新动作
7.10 注册监听器
7.11 初始化所有剩下的单实例bean对象

本节完,更多内容请查阅分类专栏:SpringBoot源码解读与原理分析

你可能感兴趣的:(spring,boot,java,后端,spring,开发语言)