基于XML的依赖注入

1.依赖注入发生的时间

当SpringIOC容器完成了Bean定义资源的定位、载入和解析注册以后,IOC容器中已经管理类Bean定义的相关数据,但是此时IOC容器还没有对所管理的Bean进行依赖注入,依赖注入在以下两种情况发生:

  • 用户第一次通过getBean方法向IOC容索要Bean时,IOC容器触发依赖注入.
  • 当用户在Bean定义资源中为<bean>元素配置了lazy-init属性,即让容器在解析注册Bean定义时进行预实例化,触发依赖注入.

BeanFactory接口定义了SpringIOC容器的基本功能规范,是Spring IOC容器所应遵守的最底层和最基本的编程规范.BeanFactory接口中定义了几个getBean方法,就是用户向IOC容器索取管理的Bean的方法,我们通过分析其子类的具体实现,理解SpringIOC容器在用户索取Bean时如何完成依赖注入.

BeanFactory

在BeanFactory中我们看到getBean(String...)函数,它的具体实现在AbstractBeanFactory中.

2.AbstractBeanFactory通过getBean向IOC容器获取被管理的Bean

AbstractBeanFactorygetBean相关方法的源码如下:

public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
    //---------------------------------------------------------------------
    // Implementation of BeanFactory interface
    //---------------------------------------------------------------------

    /**
     * 获取IOC容器中指定名称的Bean
     */
    @Override
    public Object getBean(String name) throws BeansException {
        // doGetBean 才是真正向IOC容器获取被管理Bean的过程
        return doGetBean(name, null, null, false);
    }

    /**
     * 获取IOC容器中指定名称和类型的Bean
     */
    @Override
    public <T> T getBean(String name, Class<T> requiredType) throws BeansException {
        return doGetBean(name, requiredType, null, false);
    }

    /**
     * 获取IOC容器中指定名称和参数的Bean
     */
    @Override
    public Object getBean(String name, Object... args) throws BeansException {
        return doGetBean(name, null, args, false);
    }

    /**
     * 获取IOC容器中指定名称、类型和参数的Bean
     */
    public <T> T getBean(String name, @Nullable Class<T> requiredType, @Nullable Object... args)
            throws BeansException {
        return doGetBean(name, requiredType, args, false);
    }

    /**
     * 获取 Bean 对象, 真正实现向IOC容器获取 Bean 功能, 也是触发依赖注入功能的地方
     * <p>
     * Return an instance, which may be shared or independent, of the specified bean.
     *
     * @param name          the name of the bean to retrieve
     *                      要获取 Bean 的名字
     * @param requiredType  the required type of the bean to retrieve
     *                      要获取 Bean 的类型
     * @param args          arguments to use when creating a bean instance using explicit arguments
     *                      (only applied when creating a new instance as opposed to retrieving an existing one)
     *                      创建 Bean 时传递的参数.这个参数仅限于创建 Bean 时使用.
     * @param typeCheckOnly whether the instance is obtained for a type check,
     *                      not for actual use
     *                      是否需要进行类型检查
     * @return an instance of the bean
     * @throws BeansException if the bean could not be created
     */
    @SuppressWarnings("unchecked")
    protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
            @Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
        // 根据指定的名称获取被管理Bean名称,剥离指定名称中对容器的相关依赖
        // 如果指定的是别名, 将别名转换为规范的Bean名称
        final String beanName = transformedBeanName(name);
        Object bean;

        // 从缓存中或者实例工厂中获取 Bean 对象
        // 对于单例模式的Bean, 整个IOC容器中只创建一个, 不需要重复创建
        // Eagerly check singleton cache for manually registered singletons.
        Object sharedInstance = getSingleton(beanName);
        if (sharedInstance != null && args == null) {
            if (logger.isTraceEnabled()) {
                // 指定名称的Bean在容器中已有单例模式的Bean被创建, 直接返回已经创建的Bean
                if (isSingletonCurrentlyInCreation(beanName)) {
                    logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +
                            "' that is not fully initialized yet - a consequence of a circular reference");
                } else {
                    logger.trace("Returning cached instance of singleton bean '" + beanName + "'");
                }
            }
            // 完成 FactoryBean 的相关处理,并用来获取 FactoryBean 的处理结果
            // 注意: BeanFactory是管理容器中Bean的工程, FactoryBean是创建创建对象的工厂Bean, 两者之间有区别
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        } else {
            // Fail if we're already creating this bean instance:
            // We're assumably within a circular reference.
            // 因为 Spring 只解决单例模式下得循环依赖,在原型模式下如果存在循环依赖则会抛出异常.
            if (isPrototypeCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
            }

            // 对IOC容器中是否存在指定名称的BeanDefinition进行检查
            // 首先加查是否能在当前的BeanFactory中获取的所需要的Bean, 如果不能则委托当前容器的父级容器去查询
            // 如果当前还是找不到则沿着容器的继承体系向父级容器查询
            // Check if bean definition exists in this factory.
            BeanFactory parentBeanFactory = getParentBeanFactory();
            // 当前容器的父级容器存在, 并且当前容器中不存在指定名称的Bean
            if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
                // Not found -> check parent.
                // 解析指定Bean名称的原始名称
                String nameToLookup = originalBeanName(name);
                // 如果,父类容器为 AbstractBeanFactory ,直接递归查找
                if (parentBeanFactory instanceof AbstractBeanFactory) {
                    return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
                            nameToLookup, requiredType, args, typeCheckOnly);
                // 用明确的 args 从 parentBeanFactory 中,获取 Bean 对象
                } else if (args != null) {
                    // Delegation to parent with explicit args.
                    return (T) parentBeanFactory.getBean(nameToLookup, args);
                // 用明确的 requiredType 从 parentBeanFactory 中,获取 Bean 对象
                } else if (requiredType != null) {
                    // No args -> delegate to standard getBean method.
                    return parentBeanFactory.getBean(nameToLookup, requiredType);
                // 直接使用 nameToLookup 从 parentBeanFactory 获取 Bean 对象
                } else {
                    return (T) parentBeanFactory.getBean(nameToLookup);
                }
            }

            // 如果不是仅仅做类型检查则是创建bean,这里需要记录
            if (!typeCheckOnly) {
                markBeanAsCreated(beanName);
            }

            try {
                // 从容器中获取 beanName 相应的 GenericBeanDefinition 对象,并将其转换为 RootBeanDefinition 对象
                // 更加指定Bean名称获取其父级的Bean定义, 主要解决Bean继承时子类合并父类公共属性问题
                final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                // 检查给定的合并的 BeanDefinition
                checkMergedBeanDefinition(mbd, beanName, args);

                // Guarantee initialization of beans that the current bean depends on.
                // 处理所依赖的 bean
                String[] dependsOn = mbd.getDependsOn();
                if (dependsOn != null) {
                    for (String dep : dependsOn) {
                        // 若给定的依赖 bean 已经注册为依赖给定的 bean
                        // 即循环依赖的情况,抛出 BeanCreationException 异常
                        if (isDependent(beanName, dep)) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                    "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                        }
                        // 递归调用getBean方法, 获取当前Bean的依赖Bean
                        registerDependentBean(dep, beanName);
                        try {
                            // 递归处理依赖 Bean
                            getBean(dep);
                        } catch (NoSuchBeanDefinitionException ex) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                                    "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                        }
                    }
                }

                // bean 实例化
                // Create bean instance.
                // 创建单例模式Bean的实例对象
                if (mbd.isSingleton()) {
                    // 这里使用了一个匿名内部类, 创建Bean实例对象,并且注册所依赖的对象
                    sharedInstance = getSingleton(beanName, () -> {
                        try {
                            // 创建一个指定Bean实例对象, 如果有父级继承, 则合并子类和父类的定义
                            return createBean(beanName, mbd, args);
                        }
                        catch (BeansException ex) {
                            // Explicitly remove instance from singleton cache: It might have been put there
                            // eagerly by the creation process, to allow for circular reference resolution.
                            // Also remove any beans that received a temporary reference to the bean.
                            // 显式从单例缓存中删除 Bean 实例
                            // 因为单例模式下为了解决循环依赖,可能他已经存在了,所以销毁它
                            destroySingleton(beanName);
                            throw ex;
                        }
                    });
                    // 获取给定Bean的实例对象
                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                }
                // IOC容器创建原型模式Bean实例对象
                else if (mbd.isPrototype()) {
                    // It's a prototype -> create a new instance.
                    Object prototypeInstance;
                    try {
                        // 回调beforePrototypeCreation方法, 默认的功能是注册当前创建的原型对象
                        beforePrototypeCreation(beanName);
                        // 创建指定Bean对象实例
                        prototypeInstance = createBean(beanName, mbd, args);
                    } finally {
                        // 回调afterPrototypeCreation方法, 默认的功能告诉IOC容器指定Bean的原型对象不再创建
                        afterPrototypeCreation(beanName);
                    }
                    // 获取给定Bean的实例对象
                    bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
                }
                // 要创建的Bean既不是单例模式, 也不是原型模式, 则根据Bean定义资源中配置的生命周期范围, 选择实例化Bean的合适方法
                // 这种在web应用程序中比较常用, 如: request, session, application等生命周期
                else {
                    // 获得 scopeName 对应的 Scope 对象
                    String scopeName = mbd.getScope();
                    final Scope scope = this.scopes.get(scopeName);
                    // Bean定义资源中没有配置生命周期范围, 则Bean定义不合法
                    if (scope == null) {
                        throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
                    }
                    try {
                        // 这里又使用了一个匿名内部类, 从指定的 scope 下创建 bean
                        Object scopedInstance = scope.get(beanName, () -> {
                            // 加载前置处理
                            beforePrototypeCreation(beanName);
                            try {
                                // 创建 Bean 对象
                                return createBean(beanName, mbd, args);
                            } finally {
                                // 加载后缀处理
                                afterPrototypeCreation(beanName);
                            }
                        });
                        // 从 Bean 实例中获取对象
                        bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
                    } catch (IllegalStateException ex) {
                        throw new BeanCreationException(beanName,
                                "Scope '" + scopeName + "' is not active for the current thread; consider " +
                                "defining a scoped proxy for this bean if you intend to refer to it from a singleton",
                                ex);
                    }
                }
            } catch (BeansException ex) {
                cleanupAfterBeanCreationFailure(beanName);
                throw ex;
            }
        }

        // 检查需要的类型是否符合 bean 的实际类型
        // Check if required type matches the type of the actual bean instance.
        if (requiredType != null && !requiredType.isInstance(bean)) {
            try {
                // 执行转换
                T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
                // 转换失败,抛出 BeanNotOfRequiredTypeException 异常
                if (convertedBean == null) {
                    throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
                }
                return convertedBean;
            } catch (TypeMismatchException ex) {
                if (logger.isTraceEnabled()) {
                    logger.trace("Failed to convert bean '" + name + "' to required type '" +
                            ClassUtils.getQualifiedName(requiredType) + "'", ex);
                }
                throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
            }
        }
        return (T) bean;
    }

}

通过上面对向IOC容器获取Bean方法的分析,我们可以看到在Spring中,如果Bean定义的单例模式(Singleton),则容器在创建之前先从缓存中查找,以确保整个容器中只存在一个实例对象.如果Bean定义的是原型模式(Prototype),则容器每次都会创建一个新的实例对象.除此之外,Bean定义还可以扩展为指定其生命周期范围.

上面的源码只是定义了根据Bean定义的模式,采取的不同创建Bean实例对象的策略,具体的Bean实例对象的创建过程由实现了ObejctFactory接口的匿名内部类的createBean方法完成,ObejctFactory使用委派模式,具体的Bean实例创建过程交由其实现类AbstractAutowireCapableBeanFactory完成,我们继续分析AbstractAutowireCapableBeanFactorycreateBean方法的源码,理解其创建Bean实例的具体实现过程.

3.AbstractAutowireCapableBeanFactory创建Bean实例对象

AbstractAutowireCapableBeanFactory类实现了ObejctFactory接口,创建容器指定的Bean实例对象,同时还对创建的Bean实例对象进行初始化处理.其创建Bean实例对象的方法源码如下:

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
        implements AutowireCapableBeanFactory {

    //---------------------------------------------------------------------
    // Implementation of relevant AbstractBeanFactory template methods
    //---------------------------------------------------------------------

    /**
     * 创建Bean实例对象
     * Central method of this class: creates a bean instance,
     * populates the bean instance, applies post-processors, etc.
     * @see #doCreateBean
     */
    @Override
    protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
            throws BeanCreationException {

        if (logger.isTraceEnabled()) {
            logger.trace("Creating instance of bean '" + beanName + "'");
        }
        RootBeanDefinition mbdToUse = mbd;

        // Make sure bean class is actually resolved at this point, and
        // clone the bean definition in case of a dynamically resolved Class
        // which cannot be stored in the shared merged bean definition.
        // 确保此时的 bean 已经被解析了
        // 如果获取的class 属性不为null,则克隆该 BeanDefinition
        // 主要是因为该动态解析的 class 无法保存到到共享的 BeanDefinition
        Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
        if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
            mbdToUse = new RootBeanDefinition(mbd);
            mbdToUse.setBeanClass(resolvedClass);
        }

        // Prepare method overrides.
        try {
            // 验证和准备覆盖方法
            mbdToUse.prepareMethodOverrides();
        } catch (BeanDefinitionValidationException ex) {
            throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
                    beanName, "Validation of method overrides failed", ex);
        }

        try {
            // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
            // 如果Bean配置了初始化前和初始化后的处理器, 则试图返回一个需要创建Bean的代理对象
            // 给 BeanPostProcessors 一个机会用来返回一个代理类而不是真正的类实例, AOP 的功能就是基于这个地方,参见 AbstractAutoProxyCreator
            Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
            if (bean != null) {
                return bean;
            }
        } catch (Throwable ex) {
            throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
                    "BeanPostProcessor before instantiation of bean failed", ex);
        }

        try {
            // 创建 Bean 的入口
            Object beanInstance = doCreateBean(beanName, mbdToUse, args);
            if (logger.isTraceEnabled()) {
                logger.trace("Finished creating instance of bean '" + beanName + "'");
            }
            return beanInstance;
        } catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
            // A previously detected exception with proper bean creation context already,
            // or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
            throw ex;
        } catch (Throwable ex) {
            throw new BeanCreationException(
                    mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
        }
    }

    /**
     * 真正创建 Bean 的方法
     * Actually create the specified bean. Pre-creation processing has already happened
     * at this point, e.g. checking {@code postProcessBeforeInstantiation} callbacks.
     * <p>Differentiates between default bean instantiation, use of a
     * factory method, and autowiring a constructor.
     * @param beanName the name of the bean
     * @param mbd the merged bean definition for the bean
     * @param args explicit arguments to use for constructor or factory method invocation
     * @return a new instance of the bean
     * @throws BeanCreationException if the bean could not be created
     * @see #instantiateBean
     * @see #instantiateUsingFactoryMethod
     * @see #autowireConstructor
     */
    protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
            throws BeanCreationException {

        // Instantiate the bean.
        // BeanWrapper 是对 Bean 的包装,其接口中所定义的功能很简单包括设置获取被包装的对象,获取被包装 bean 的属性描述器
        BeanWrapper instanceWrapper = null;
        // 单例模型,则从未完成的 FactoryBean 缓存中删除
        if (mbd.isSingleton()) {
            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
        }
        // 使用合适的实例化策略来创建新的实例:工厂方法、构造函数自动注入、简单初始化
        if (instanceWrapper == null) {
            instanceWrapper = createBeanInstance(beanName, mbd, args);
        }
        // 包装的实例对象
        final Object bean = instanceWrapper.getWrappedInstance();
        // 包装的实例对象的类型
        Class<?> beanType = instanceWrapper.getWrappedClass();
        if (beanType != NullBean.class) {
            mbd.resolvedTargetType = beanType;
        }

        // Allow post-processors to modify the merged bean definition.
        // 判断是否有后置处理
        // 如果有后置处理,则允许后置处理修改 BeanDefinition
        synchronized (mbd.postProcessingLock) {
            if (!mbd.postProcessed) {
                try {
                    // 后置处理修改 BeanDefinition
                    applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                } catch (Throwable ex) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                            "Post-processing of merged bean definition failed", ex);
                }
                mbd.postProcessed = true;
            }
        }

        // Eagerly cache singletons to be able to resolve circular references
        // even when triggered by lifecycle interfaces like BeanFactoryAware.
        // 解决单例模式的循环依赖
        boolean earlySingletonExposure = (mbd.isSingleton() // 单例模式
                && this.allowCircularReferences // 运行循环依赖
                && isSingletonCurrentlyInCreation(beanName)); // 当前单例 bean 是否正在被创建
        if (earlySingletonExposure) {
            if (logger.isTraceEnabled()) {
                logger.trace("Eagerly caching bean '" + beanName +
                        "' to allow for resolving potential circular references");
            }
            // 这里是一个匿名内部类, 为了防止循环引用, 尽早持有对象的引用
            // 提前将创建的 bean 实例加入到 singletonFactories 中, 为了后期避免循环依赖
            addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
        }

        // Initialize the bean instance.
        // 开始初始化 bean 实例对象
        Object exposedObject = bean;
        try {
            // 对 bean 进行填充,将各个属性值注入,其中,可能存在依赖于其他 bean 的属性,则会递归初始依赖 bean
            populateBean(beanName, mbd, instanceWrapper);
            // 调用初始化方法
            exposedObject = initializeBean(beanName, exposedObject, mbd);
        } catch (Throwable ex) {
            if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
                throw (BeanCreationException) ex;
            } else {
                throw new BeanCreationException(
                        mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
            }
        }

        // 循环依赖处理
        if (earlySingletonExposure) {
            // 获取指定名称的已注册的单例模式Bean对象 earlySingletonReference
            Object earlySingletonReference = getSingleton(beanName, false);
            // 只有在存在循环依赖的情况下,earlySingletonReference 才不会为空
            if (earlySingletonReference != null) {
                // 如果 exposedObject 没有在初始化方法中被改变,也就是没有被增强
                if (exposedObject == bean) {
                    exposedObject = earlySingletonReference;
                // 处理依赖: 当前Bean依赖其它Bean, 并且当发生循环引用时不允许新创建实例对象
                } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                    String[] dependentBeans = getDependentBeans(beanName);
                    Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
                    // 获取当前Bean所依赖的其它Bean
                    for (String dependentBean : dependentBeans) {
                        // 对依赖Bean进行类型检查
                        if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
                            actualDependentBeans.add(dependentBean);
                        }
                    }
                    if (!actualDependentBeans.isEmpty()) {
                        throw new BeanCurrentlyInCreationException(beanName,
                                "Bean with name '" + beanName + "' has been injected into other beans [" +
                                StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
                                "] in its raw version as part of a circular reference, but has eventually been " +
                                "wrapped. This means that said other beans do not use the final version of the " +
                                "bean. This is often the result of over-eager type matching - consider using " +
                                "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
                    }
                }
            }
        }

        // Register bean as disposable.
        // 注册完成依赖注入的 bean
        try {
            registerDisposableBeanIfNecessary(beanName, bean, mbd);
        } catch (BeanDefinitionValidationException ex) {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
        }

        return exposedObject;
    }
}

通过对方法源码的分析,我们看到具体的依赖注入实现在以下两个方法中:

  • createBeanInstance: 生成Bean所包含的java对象实例.
  • populateBean: 对Bean属性的依赖注入进行处理.

下面继续分析这两个方法的代码实现.

4.createBeanInstance方法创建Bean的java实例对象

在createBeanInstance方法中,根据指定的初始化策略,使用静态工厂、工厂方法或者容器的自动装配特性生成java实例对象,创建对象的源码如下:

/**
 * 创建Bean的实例对象
 */
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
    // Make sure bean class is actually resolved at this point.
    // 解析 bean ,将 bean 类名解析为 class 引用.
    Class<?> beanClass = resolveBeanClass(mbd, beanName);

    // 校验
    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());
    }

    // 如果存在 Supplier 回调,则使用给定的回调方法初始化策略
    Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
    if (instanceSupplier != null) {
        return obtainFromSupplier(instanceSupplier, beanName);
    }

    // 使用 FactoryBean 的 factory-method 来创建,支持静态工厂和实例工厂
    if (mbd.getFactoryMethodName() != null)  {
        return instantiateUsingFactoryMethod(beanName, mbd, args);
    }

    // Shortcut when re-creating the same bean...
    // 使用容器的自动装配方法进行实例化
    boolean resolved = false;
    boolean autowireNecessary = false;
    if (args == null) {
        // constructorArgumentLock 构造函数的常用锁
        synchronized (mbd.constructorArgumentLock) {
            // 如果已缓存的解析的构造函数或者工厂方法不为空,则可以利用构造函数解析
            // 因为需要根据参数确认到底使用哪个构造函数,该过程比较消耗性能,所有采用缓存机制
            if (mbd.resolvedConstructorOrFactoryMethod != null) {
                resolved = true;
                autowireNecessary = mbd.constructorArgumentsResolved;
            }
        }
    }
    // 已经解析好了,直接注入即可
    if (resolved) {
        // autowire 自动注入,调用构造函数自动注入,容器的自动装配是根据参数类型匹配Bean的构造方法
        if (autowireNecessary) {
            return autowireConstructor(beanName, mbd, null, null);
        } else {
            // 使用默认构造函数构造
            return instantiateBean(beanName, mbd);
        }
    }

    // Candidate constructors for autowiring?
    // 确定解析的构造函数
    // 主要是检查已经注册的 SmartInstantiationAwareBeanPostProcessor
    Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
    // 有参数情况时,创建 Bean .先利用参数个数,类型等,确定最精确匹配的构造方法.
    if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
            mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
        // 使用容器的自动装配特性, 调用匹配的构造方法实例化
        return autowireConstructor(beanName, mbd, ctors, args);
    }

    // Preferred constructors for default construction?
    // 选择构造方法,创建 Bean .
    ctors = mbd.getPreferredConstructors();
    if (ctors != null) {
        // args = null
        return autowireConstructor(beanName, mbd, ctors, null);
    }

    // No special handling: simply use no-arg constructor.
    // 有参数时,又没获取到构造方法,则只能调用无参构造方法来创建实例了(兜底方法)
    return instantiateBean(beanName, mbd);
}


/** Strategy for creating bean instances. */
private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();

/**
 * Return the instantiation strategy to use for creating bean instances.
 */
protected InstantiationStrategy getInstantiationStrategy() {
    return this.instantiationStrategy;
}

/**
 * Instantiate the given bean using its default constructor.
 * @param beanName the name of the bean
 * @param mbd the bean definition for the bean
 * @return a BeanWrapper for the new instance
 */
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
    try {
        Object beanInstance;
        final BeanFactory parent = this;
        // 安全模式
        if (System.getSecurityManager() != null) {
            beanInstance = AccessController.doPrivileged((PrivilegedAction<Object>) () ->
                    // 获得 InstantiationStrategy 对象,并使用它,创建 Bean 对象
                    getInstantiationStrategy().instantiate(mbd, beanName, parent),
                    getAccessControlContext());
        } else {
            // 获得 InstantiationStrategy 对象,并使用它,创建 Bean 对象
            beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
        }
        // 封装 BeanWrapperImpl  并完成初始化
        BeanWrapper bw = new BeanWrapperImpl(beanInstance);
        initBeanWrapper(bw);
        return bw;
    } catch (Throwable ex) {
        throw new BeanCreationException(
                mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);
    }
}

经过对上面的代码分析,我们可以看出,对使用工厂方法和自动装配特性的Bean的实例化相当比较清楚,调用相应的工厂方法或者参数匹配的构造方法即可完成实例化对象的工作,但是对于我们最常使用的默认无参构造方法就需要使用相应的初始化策略(JDK的反射机制或者CGLIB)来进行初始化了,在方法getInstantiationStrategy().instantiate()中就具体实现类使用初始策略实例化对象.

5.SimpleInstantiationStrategy类使用默认的无参构造方法创建Bean实例化对象

在使用默认的无参构造方法创建Bean的实例化对象时,方法getInstantiationStrategy().instantiate()调用了SimpleInstantiationStrategy类中的实例化Bean的方法,其源码如下:

public class SimpleInstantiationStrategy implements InstantiationStrategy {
    /**
     * 使用初始化策略实例化 Bean 对象
     * @param bd the bean definition
     * @param beanName the name of the bean when it is created in this context.
     * The name can be {@code null} if we are autowiring a bean which doesn't
     * belong to the factory.
     * @param owner the owning BeanFactory
     * @return
     */
    @Override
    public Object instantiate(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
        // Don't override the class with CGLIB if no overrides.
        // 如果Bean定义中没有方法覆盖,则就不需要CGLIB父类类的方法, 直接使用反射实例化即可
        if (!bd.hasMethodOverrides()) {
            Constructor<?> constructorToUse;
            synchronized (bd.constructorArgumentLock) {
                // 获得对象的构造方法或工厂方法 constructorToUse
                constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
                if (constructorToUse == null) {
                    // 使用JDK的反射机制, 判断要实例化的Bean是否是接口
                    final Class<?> clazz = bd.getBeanClass();
                    // 如果是接口,抛出 BeanInstantiationException 异常
                    if (clazz.isInterface()) {
                        throw new BeanInstantiationException(clazz, "Specified class is an interface");
                    }
                    try {
                        // 从 clazz 中,获得构造方法
                        // 安全模式
                        if (System.getSecurityManager() != null) {
                            // 匿名内部类, 使用反射机制获取 Bean 的构造方法
                            constructorToUse = AccessController.doPrivileged(
                                    (PrivilegedExceptionAction<Constructor<?>>) clazz::getDeclaredConstructor);
                        } else {
                            constructorToUse =    clazz.getDeclaredConstructor();
                        }
                        // 标记 resolvedConstructorOrFactoryMethod 属性
                        bd.resolvedConstructorOrFactoryMethod = constructorToUse;
                    } catch (Throwable ex) {
                        throw new BeanInstantiationException(clazz, "No default constructor found", ex);
                    }
                }
            }
            // 通过 BeanUtils 直接使用构造器对象"构造方法.newInstance(arg)"来实例化 Bean 对象
            return BeanUtils.instantiateClass(constructorToUse);
        } else {
            // Must generate CGLIB subclass.
            // 生成 CGLIB 创建的子类对象
            return instantiateWithMethodInjection(bd, beanName, owner);
        }
    }
}

通过上面的代码分析,我们看到了如果Bean有方法被覆盖了,则使用JDK的反射机制进行实例化,否则,使用CGLIB进行实例化.

instantiateWithMethodInjection方法调用SimpleInstantiationStrategy的子类CglibSubclassingInstantiationStrategy使用CGLIB来进行初始化,其源码如下:

public class CglibSubclassingInstantiationStrategy extends SimpleInstantiationStrategy {

    @Override
    protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner) {
        return instantiateWithMethodInjection(bd, beanName, owner, null);
    }

    @Override
    protected Object instantiateWithMethodInjection(RootBeanDefinition bd, @Nullable String beanName, BeanFactory owner, @Nullable Constructor<?> ctor, Object... args) {
        // Must generate CGLIB subclass...
        // 通过CGLIB生成一个子类对象
        return new CglibSubclassCreator(bd, owner).instantiate(ctor, args);
    }

    private static class CglibSubclassCreator {
        /**
         * 使用 CGLIB 进行 Bean 对象实例化
         * Create a new instance of a dynamically generated subclass implementing the
         * required lookups.
         * @param ctor constructor to use. If this is {@code null}, use the
         * no-arg constructor (no parameterization, or Setter Injection)
         * @param args arguments to use for the constructor.
         * Ignored if the {@code ctor} parameter is {@code null}.
         * @return new instance of the dynamically generated subclass
         */
        public Object instantiate(@Nullable Constructor<?> ctor, Object... args) {
            // 通过 Cglib 创建一个代理类
            Class<?> subclass = createEnhancedSubclass(this.beanDefinition);
            Object instance;
            // 没有构造器,通过 BeanUtils 使用默认构造器创建一个bean实例
            if (ctor == null) {
                instance = BeanUtils.instantiateClass(subclass);
            } else {
                try {
                    // 获取代理类对应的构造器对象,并实例化 bean
                    Constructor<?> enhancedSubclassConstructor = subclass.getConstructor(ctor.getParameterTypes());
                    instance = enhancedSubclassConstructor.newInstance(args);
                } catch (Exception ex) {
                    throw new BeanInstantiationException(this.beanDefinition.getBeanClass(),
                            "Failed to invoke constructor for CGLIB enhanced subclass [" + subclass.getName() + "]", ex);
                }
            }
            // SPR-10785: set callbacks directly on the instance instead of in the
            // enhanced class (via the Enhancer) in order to avoid memory leaks.
            // 为了避免 memory leaks 异常,直接在 bean 实例上设置回调对象
            Factory factory = (Factory) instance;
            factory.setCallbacks(new Callback[] {NoOp.INSTANCE,
                    new LookupOverrideMethodInterceptor(this.beanDefinition, this.owner),
                    new ReplaceOverrideMethodInterceptor(this.beanDefinition, this.owner)});
            return instance;
        }

        /**
         * Create an enhanced subclass of the bean class for the provided bean
         * definition, using CGLIB.
         */
        private Class<?> createEnhancedSubclass(RootBeanDefinition beanDefinition) {
            // CGLIB 中的类
            Enhancer enhancer = new Enhancer();
            // 将Bean本身作为其基类
            enhancer.setSuperclass(beanDefinition.getBeanClass());
            enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
            if (this.owner instanceof ConfigurableBeanFactory) {
                ClassLoader cl = ((ConfigurableBeanFactory) this.owner).getBeanClassLoader();
                enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(cl));
            }
            enhancer.setCallbackFilter(new MethodOverrideCallbackFilter(beanDefinition));
            enhancer.setCallbackTypes(CALLBACK_TYPES);
            // 使用CGLIB的createClass方法生成实例对象
            return enhancer.createClass();
        }
    }
}

CGLIB是一个常用的字节码生成器的类库,它提供了一系列API实现java字节码的生成和转换功能.我们在学习JDK的动态代理时都知道,JDK的动态代理只能针对接口,如果一个类没有实现任何接口,要对其进行动态代理只能使用CGLIB.

6.populateBean方法对Bean属性的依赖注入

在上面(3)的分析中我们已经了解到Bean的依赖注入分为以下两个过程:

  • createBeanInstance: 生成Bean所包含的Java对象实例
  • populateBean: 对Bean属性的依赖注入进行处理

上面我们已经分析了容器初始化生成Bean所包含的Java实例对象的过程,现在我们继续分析生成对象后,Spring IOC容器是如何将Bean的属性依赖关系注入Bean实例对象中并设置好的,属性依赖注入的代码如下:

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
        implements AutowireCapableBeanFactory {

    /**
     * 将 Bean 属性设置到生成的实例对象上
     * Populate the bean instance in the given BeanWrapper with the property values
     * from the bean definition.
     * @param beanName the name of the bean
     * @param mbd the bean definition for the bean
     * @param bw the BeanWrapper with bean instance
     */
    @SuppressWarnings("deprecation")  // for postProcessPropertyValues
    protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {

        // 没有实例化对象
        if (bw == null) {
            // 有属性,则抛出 BeanCreationException 异常
            if (mbd.hasPropertyValues()) {
                throw new BeanCreationException(
                        mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
            // 没有属性,直接 return 返回
            } else {
                // Skip property population phase for null instance.
                return;
            }
        }

        // 在设置属性之前给 InstantiationAwareBeanPostProcessors 最后一次改变 bean 的机会
        // 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.
        boolean continueWithPropertyPopulation = true;
        // bean 不是"合成"的,即未由应用程序本身定义
        if (!mbd.isSynthetic()
                // 是否持有 InstantiationAwareBeanPostProcessor
                && hasInstantiationAwareBeanPostProcessors()) {
            // 迭代所有的 BeanPostProcessors
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                // 如果为 InstantiationAwareBeanPostProcessor
                if (bp instanceof InstantiationAwareBeanPostProcessor) {
                    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                    // 返回值为是否继续填充 bean
                    // postProcessAfterInstantiation:如果应该在 bean上面设置属性则返回 true,否则返回 false
                    // 一般情况下,应该是返回true .
                    // 返回 false 的话,将会阻止在此 Bean 实例上调用任何后续的 InstantiationAwareBeanPostProcessor 实例.
                    if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                        continueWithPropertyPopulation = false;
                        break;
                    }
                }
            }
        }
        // 如果后续处理器发出停止填充命令,则终止后续操作
        if (!continueWithPropertyPopulation) {
            return;
        }

        // 获取容器在解析 bean 定义资源时为 BeanDefinition 中设置的属性值
        PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

        // 自动注入
        if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
            // 将 PropertyValues 封装成 MutablePropertyValues 对象
            // MutablePropertyValues 允许对属性进行简单的操作,并提供构造函数以支持Map的深度复制和构造.
            MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
            // Add property values based on autowire by name if applicable.
            // 根据名称自动注入
            if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
                autowireByName(beanName, mbd, bw, newPvs);
            }
            // Add property values based on autowire by type if applicable.
            // 根据类型自动注入
            if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
                autowireByType(beanName, mbd, bw, newPvs);
            }
            pvs = newPvs;
        }

        // 是否已经注册了 InstantiationAwareBeanPostProcessors
        boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
        // 是否需要进行【依赖检查】
        boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

        // BeanPostProcessor 处理
        PropertyDescriptor[] filteredPds = null;
        if (hasInstAwareBpps) {
            if (pvs == null) {
                pvs = mbd.getPropertyValues();
            }
            // 遍历 BeanPostProcessor 数组
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                if (bp instanceof InstantiationAwareBeanPostProcessor) {
                    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                    // 对所有需要依赖检查的属性进行后处理
                    PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
                    if (pvsToUse == null) {
                        // 从 bw 对象中提取 PropertyDescriptor 结果集
                        // PropertyDescriptor:可以通过一对存取方法提取一个属性
                        if (filteredPds == null) {
                            filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                        }
                        pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                        if (pvsToUse == null) {
                            return;
                        }
                    }
                    pvs = pvsToUse;
                }
            }
        }

        // 依赖检查
        if (needsDepCheck) {
            if (filteredPds == null) {
                filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
            }
            // 依赖检查,对应 depends-on 属性
            checkDependencies(beanName, mbd, filteredPds, pvs);
        }

        // 将属性应用到 bean 中
        if (pvs != null) {
            applyPropertyValues(beanName, mbd, bw, pvs);
        }
    }

    /**
     * 解析并注入依赖属性的过程
     */
    protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
        if (pvs.isEmpty()) {
            return;
        }

        // 设置 BeanWrapperImpl 的 SecurityContext 属性
        if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
            // 设置安全上下文, JDK 安全机制
            ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
        }

        // MutablePropertyValues 类型属性
        MutablePropertyValues mpvs = null;

        // 原始类型
        List<PropertyValue> original;
        // 获得 original
        if (pvs instanceof MutablePropertyValues) {
            mpvs = (MutablePropertyValues) pvs;
            // 属性值已经转换
            if (mpvs.isConverted()) {
                // Shortcut: use the pre-converted values as-is.
                try {
                    // 为实例化对象设置属性值 ,依赖注入真真正正地实现在此!!!!!
                    bw.setPropertyValues(mpvs);
                    return;
                } catch (BeansException ex) {
                    throw new BeanCreationException(
                            mbd.getResourceDescription(), beanName, "Error setting property values", ex);
                }
            }
            // 获取属性值对象的原始类型值
            original = mpvs.getPropertyValueList();
        } else {
            // 如果 pvs 不是 MutablePropertyValues 类型,则直接使用原始类型
            original = Arrays.asList(pvs.getPropertyValues());
        }

        // 获取 TypeConverter = 获取用户自定义的类型转换
        TypeConverter converter = getCustomTypeConverter();
        if (converter == null) {
            converter = bw;
        }

        // 获取一个Bean定义属性值解析器, 将Bean定义中的属性值解析为Bean实例对象的实际值
        BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

        // Create a deep copy, resolving any references for values.
        // 为属性的解析值创建一个拷贝,将拷贝的数据注入到实例对象中
        List<PropertyValue> deepCopy = new ArrayList<>(original.size());
        boolean resolveNecessary = false;
        // 遍历属性,将属性转换为对应类的对应属性的类型
        for (PropertyValue pv : original) {
            // 属性值不需要转换
            if (pv.isConverted()) {
                deepCopy.add(pv);
            // 属性值需要转换
            } else {
                String propertyName = pv.getName();
                // 原始的属性值,即转换之前的属性值
                Object originalValue = pv.getValue();
                // 转换属性值,例如将引用转换为IoC容器中实例化对象引用 !!!!! 对属性值的解析!!
                Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
                // 转换之后的属性值
                Object convertedValue = resolvedValue;
                boolean convertible = bw.isWritableProperty(propertyName) &&
                        // 属性值是否可以转换
                        !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
                        // 使用用户自定义的类型转换器转换属性值
                if (convertible) {
                    convertedValue = convertForProperty(resolvedValue, propertyName, bw, converter);
                }
                // Possibly store converted value in merged bean definition,
                // in order to avoid re-conversion for every created bean instance.
                // 存储转换后的属性值,避免每次属性注入时的转换工作
                if (resolvedValue == originalValue) {
                    if (convertible) {
                        // 设置属性转换之后的值
                        pv.setConvertedValue(convertedValue);
                    }
                    deepCopy.add(pv);
                    // 属性是可转换的,且属性原始值是字符串类型,且属性的原始类型值不是动态生成的字符串,且属性的原始值不是集合或者数组类型
                } else if (convertible && originalValue instanceof TypedStringValue &&
                        !((TypedStringValue) originalValue).isDynamic() &&
                        !(convertedValue instanceof Collection || ObjectUtils.isArray(convertedValue))) {
                    pv.setConvertedValue(convertedValue);
                    deepCopy.add(pv);
                } else {
                    resolveNecessary = true;
                    // 重新封装属性的值
                    deepCopy.add(new PropertyValue(pv, convertedValue));
                }
            }
        }
        // 标记属性值已经转换过
        if (mpvs != null && !resolveNecessary) {
            mpvs.setConverted();
        }

        // Set our (possibly massaged) deep copy.
        // 进行属性依赖注入,依赖注入的真真正正实现依赖的注入方法在此!!!
        try {
            bw.setPropertyValues(new MutablePropertyValues(deepCopy));
        } catch (BeansException ex) {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Error setting property values", ex);
        }
    }
}

分析上述代码,我们可以看出,对属性的注入过程分以下两种情况:

  • 属性值类型不需要转换时,不需要解析属性值,直接准备进行依赖注入.
  • 属性值需要进行类型转换时,如对其他对象的引用等,首先需要解析属性值,然后对解析后的属性值进行依赖注入.

对属性值的解析是在BeanDefinitionValueResolver类中的resolveValueIfNecessary方法中进行的,对属性值的依赖注入是通过bw.setPropertyValues方法实现的,在分析属性值的依赖注入之前,我们先分析一下对属性值的解析过程.

7.BeanDefinitionValueResolver解析属性值

当容器在对属性进行依赖注入时,如果发现属性值需要进行类型转换,如属性值是容器中另一个Bean实例对象的引用,则容器首先需要根据属性值解析出所引用的对象,然后才能将该引用对象注入到目标实例对象的属性上去,对属性进行解析的由resolveValueIfNecessary方法实现,其源码如下:

/**
 * Helper class for use in bean factory implementations,
 * resolving values contained in bean definition objects
 * into the actual values applied to the target bean instance.
 *
 * <p>Operates on an {@link AbstractBeanFactory} and a plain
 * {@link org.springframework.beans.factory.config.BeanDefinition} object.
 * Used by {@link AbstractAutowireCapableBeanFactory}.
 *
 * @author Juergen Hoeller
 * @since 1.2
 * @see AbstractAutowireCapableBeanFactory
 */
class BeanDefinitionValueResolver {
    /**
     * 解析属性值, 对注入类型进行转换
     */
    @Nullable
    public Object resolveValueIfNecessary(Object argName, @Nullable Object value) {
        // We must check each value to see whether it requires a runtime reference
        // to another bean to be resolved.
        // 对引用类型的属性进行解析
        if (value instanceof RuntimeBeanReference) {
            RuntimeBeanReference ref = (RuntimeBeanReference) value;
            // 调用引用类型属性的解析方法
            return resolveReference(argName, ref);
        }
        // 对属性值是引用容器中另一个 Bean 名称的解析
        else if (value instanceof RuntimeBeanNameReference) {
            String refName = ((RuntimeBeanNameReference) value).getBeanName();
            refName = String.valueOf(doEvaluate(refName));
            // 从容器中获取指定名称的的 Bean
            if (!this.beanFactory.containsBean(refName)) {
                throw new BeanDefinitionStoreException(
                        "Invalid bean name '" + refName + "' in bean reference for " + argName);
            }
            return refName;
        }
        // 对 Bean 类型属性的解析, 主要是 Bean 中的内部类
        else if (value instanceof BeanDefinitionHolder) {
            // Resolve BeanDefinitionHolder: contains BeanDefinition with name and aliases.
            BeanDefinitionHolder bdHolder = (BeanDefinitionHolder) value;
            return resolveInnerBean(argName, bdHolder.getBeanName(), bdHolder.getBeanDefinition());
        }
        else if (value instanceof BeanDefinition) {
            // Resolve plain BeanDefinition, without contained name: use dummy name.
            BeanDefinition bd = (BeanDefinition) value;
            String innerBeanName = "(inner bean)" + BeanFactoryUtils.GENERATED_BEAN_NAME_SEPARATOR +
                    ObjectUtils.getIdentityHexString(bd);
            return resolveInnerBean(argName, innerBeanName, bd);
        }
        // 对集合数组类型的属性解析
        else if (value instanceof ManagedArray) {
            // May need to resolve contained runtime references.
            ManagedArray array = (ManagedArray) value;
            // 获取数组的类型
            Class<?> elementType = array.resolvedElementType;
            if (elementType == null) {
                String elementTypeName = array.getElementTypeName();
                if (StringUtils.hasText(elementTypeName)) {
                    try {
                        // 使用反射机制创建指定类型的对象
                        elementType = ClassUtils.forName(elementTypeName, this.beanFactory.getBeanClassLoader());
                        array.resolvedElementType = elementType;
                    }
                    catch (Throwable ex) {
                        // Improve the message by showing the context.
                        throw new BeanCreationException(
                                this.beanDefinition.getResourceDescription(), this.beanName,
                                "Error resolving array type for " + argName, ex);
                    }
                }
                // 没有获取到数组的类型, 也没有获取到数组元素的类型, 则直接设置数组的类型为Object
                else {
                    elementType = Object.class;
                }
            }
            return resolveManagedArray(argName, (List<?>) value, elementType);
        }
        // 解析list类型的属性值
        else if (value instanceof ManagedList) {
            // May need to resolve contained runtime references.
            return resolveManagedList(argName, (List<?>) value);
        }
        // 解析set类型的属性值
        else if (value instanceof ManagedSet) {
            // May need to resolve contained runtime references.
            return resolveManagedSet(argName, (Set<?>) value);
        }
        // 解析map类型的属性值
        else if (value instanceof ManagedMap) {
            // May need to resolve contained runtime references.
            return resolveManagedMap(argName, (Map<?, ?>) value);
        }
        // 解析props类型的属性值, props其实就是key和value均为字符串的map
        else if (value instanceof ManagedProperties) {
            Properties original = (Properties) value;
            // 创建一个拷贝, 用于作为解析后的返回值
            Properties copy = new Properties();
            original.forEach((propKey, propValue) -> {
                if (propKey instanceof TypedStringValue) {
                    propKey = evaluate((TypedStringValue) propKey);
                }
                if (propValue instanceof TypedStringValue) {
                    propValue = evaluate((TypedStringValue) propValue);
                }
                if (propKey == null || propValue == null) {
                    throw new BeanCreationException(
                            this.beanDefinition.getResourceDescription(), this.beanName,
                            "Error converting Properties key/value pair for " + argName + ": resolved to null");
                }
                copy.put(propKey, propValue);
            });
            return copy;
        }
        // 解析字符串类型的属性值
        else if (value instanceof TypedStringValue) {
            // Convert value to target type here.
            TypedStringValue typedStringValue = (TypedStringValue) value;
            Object valueObject = evaluate(typedStringValue);
            try {
                // 获取属性的目标类型
                Class<?> resolvedTargetType = resolveTargetType(typedStringValue);
                if (resolvedTargetType != null) {
                    // 对目标类型的属性进行解析, 递归调用
                    return this.typeConverter.convertIfNecessary(valueObject, resolvedTargetType);
                }
                // 没有获取到属性的目标对象, 则按Object类型返回
                else {
                    return valueObject;
                }
            }
            catch (Throwable ex) {
                // Improve the message by showing the context.
                throw new BeanCreationException(
                        this.beanDefinition.getResourceDescription(), this.beanName,
                        "Error converting typed String value for " + argName, ex);
            }
        }
        else if (value instanceof NullBean) {
            return null;
        }
        else {
            return evaluate(value);
        }
    }

    /**
     * 解析引用类型的属性值
     */
    @Nullable
    private Object resolveReference(Object argName, RuntimeBeanReference ref) {
        try {
            Object bean;
            // 获取引用的 Bean 名称
            String refName = ref.getBeanName();
            refName = String.valueOf(doEvaluate(refName));
            // 如果引用的对象在父类容器中, 则从父类容器中获取指定的引用对象
            if (ref.isToParent()) {
                if (this.beanFactory.getParentBeanFactory() == null) {
                    throw new BeanCreationException(
                            this.beanDefinition.getResourceDescription(), this.beanName,
                            "Can't resolve reference to bean '" + refName +
                            "' in parent factory: no parent factory available");
                }
                bean = this.beanFactory.getParentBeanFactory().getBean(refName);
            }
            // 从当前的容器中获取指定的引用 Bean 对象, 如果指定的 Bean 没有被实例化, 则会递归触发引用 Bean 的初始化和依赖注入
            else {
                bean = this.beanFactory.getBean(refName);
                // 将当前实例化对象的依赖 引用对象
                this.beanFactory.registerDependentBean(refName, this.beanName);
            }
            if (bean instanceof NullBean) {
                bean = null;
            }
            return bean;
        }
        catch (BeansException ex) {
            throw new BeanCreationException(
                    this.beanDefinition.getResourceDescription(), this.beanName,
                    "Cannot resolve reference to bean '" + ref.getBeanName() + "' while setting " + argName, ex);
        }
    }

    /**
     * 解析array类型的属性
     * For each element in the managed array, resolve reference if necessary.
     */
    private Object resolveManagedArray(Object argName, List<?> ml, Class<?> elementType) {
        // 创建一个指定类型的数组, 用于存放和返回解析后的数组
        Object resolved = Array.newInstance(elementType, ml.size());
        for (int i = 0; i < ml.size(); i++) {
            // 递归解析array的每一个元素, 并将解析后的值设置到 resolved 数组中, 索引为i
            Array.set(resolved, i,
                    resolveValueIfNecessary(new KeyedArgName(argName, i), ml.get(i)));
        }
        return resolved;
    }
}

通过上面的代码分析,我们明白了Spring是如何将引用类型,内部类以及集合类型等属性进行解析的,属性值解析完成后就可以进行依赖注入了,依赖注入的过程就是Bean对象实例设置到它所依赖的Bean对象属性上去,在第6步中我们已经说过,依赖注入是通过bw.setPropertyValues方法实现的,该方法也使用了委托模式,在BeanWrapper接口中至少定义了方法声明,依赖注入的具体实现交由其实现类BeanWrapperImpl来完成,下面我们就分析依BeanWrapperImpl中赖注入相关的源码.

8.BeanWrapperImpl对Bean属性的依赖注入

BeanWrapperImpl类主要是对容器中完成初始化的Bean实例对象进行属性的依赖注入,即把Bean对象设置到它所依赖的另一个Bean的属性中去.然而,BeanWrapperImpl中的注入方法实际上由AbstractNestablePropertyAccessor来实现的,其相关源码如下:

public class BeanWrapperImpl extends AbstractNestablePropertyAccessor implements BeanWrapper {
    ......
}

public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyAccessor {
    /**
     * 实现属性依赖注入功能
     */
    protected void setPropertyValue(PropertyTokenHolder tokens, PropertyValue pv) throws BeansException {
        if (tokens.keys != null) {
            processKeyedProperty(tokens, pv);
        }
        else {
            processLocalProperty(tokens, pv);
        }
    }

    private void processKeyedProperty(PropertyTokenHolder tokens, PropertyValue pv) {
        // 调用属性的 getter(readerMethod)方法, 获取属性的值
        Object propValue = getPropertyHoldingValue(tokens);
        PropertyHandler ph = getLocalPropertyHandler(tokens.actualName);
        if (ph == null) {
            throw new InvalidPropertyException(
                    getRootClass(), this.nestedPath + tokens.actualName, "No property handler found");
        }
        Assert.state(tokens.keys != null, "No token keys");
        String lastKey = tokens.keys[tokens.keys.length - 1];

        // 注入 array 类型的属性值
        if (propValue.getClass().isArray()) {
            Class<?> requiredType = propValue.getClass().getComponentType();
            int arrayIndex = Integer.parseInt(lastKey);
            Object oldValue = null;
            try {
                if (isExtractOldValueForEditor() && arrayIndex < Array.getLength(propValue)) {
                    oldValue = Array.get(propValue, arrayIndex);
                }
                Object convertedValue = convertIfNecessary(tokens.canonicalName, oldValue, pv.getValue(),
                        requiredType, ph.nested(tokens.keys.length));
                // 获取集合类型属性的长度
                int length = Array.getLength(propValue);
                if (arrayIndex >= length && arrayIndex < this.autoGrowCollectionLimit) {
                    Class<?> componentType = propValue.getClass().getComponentType();
                    Object newArray = Array.newInstance(componentType, arrayIndex + 1);
                    System.arraycopy(propValue, 0, newArray, 0, length);
                    setPropertyValue(tokens.actualName, newArray);
                    // 调用属性的 getter(readerMethod)方法, 获取属性的值
                    propValue = getPropertyValue(tokens.actualName);
                }
                // 将属性的值赋值给数组中的元素
                Array.set(propValue, arrayIndex, convertedValue);
            }
            catch (IndexOutOfBoundsException ex) {
                throw new InvalidPropertyException(getRootClass(), this.nestedPath + tokens.canonicalName,
                        "Invalid array index in property path '" + tokens.canonicalName + "'", ex);
            }
        }

        // 注入list类型的属性值
        else if (propValue instanceof List) {
            // 获取list集合的类型
            Class<?> requiredType = ph.getCollectionType(tokens.keys.length);
            List<Object> list = (List<Object>) propValue;
            // 获取list集合的size
            int index = Integer.parseInt(lastKey);
            Object oldValue = null;
            if (isExtractOldValueForEditor() && index < list.size()) {
                oldValue = list.get(index);
            }
            Object convertedValue = convertIfNecessary(tokens.canonicalName, oldValue, pv.getValue(),
                    requiredType, ph.nested(tokens.keys.length));
            int size = list.size();
            // 如果list的长度大于属性值的长度, 则多于的元素赋值为null
            if (index >= size && index < this.autoGrowCollectionLimit) {
                for (int i = size; i < index; i++) {
                    try {
                        list.add(null);
                    }
                    catch (NullPointerException ex) {
                        throw new InvalidPropertyException(getRootClass(), this.nestedPath + tokens.canonicalName,
                                "Cannot set element with index " + index + " in List of size " +
                                size + ", accessed using property path '" + tokens.canonicalName +
                                "': List does not support filling up gaps with null elements");
                    }
                }
                list.add(convertedValue);
            }
            else {
                try {
                    // 将值添加到list中
                    list.set(index, convertedValue);
                }
                catch (IndexOutOfBoundsException ex) {
                    throw new InvalidPropertyException(getRootClass(), this.nestedPath + tokens.canonicalName,
                            "Invalid list index in property path '" + tokens.canonicalName + "'", ex);
                }
            }
        }

        // 注入map类型的属性值
        else if (propValue instanceof Map) {
            // 获取map集合的key类型
            Class<?> mapKeyType = ph.getMapKeyType(tokens.keys.length);
            // 获取map集合的value类型
            Class<?> mapValueType = ph.getMapValueType(tokens.keys.length);
            Map<Object, Object> map = (Map<Object, Object>) propValue;
            // IMPORTANT: Do not pass full property name in here - property editors
            // must not kick in for map keys but rather only for map values.
            TypeDescriptor typeDescriptor = TypeDescriptor.valueOf(mapKeyType);
            // 解析map类型属性的key
            Object convertedMapKey = convertIfNecessary(null, null, lastKey, mapKeyType, typeDescriptor);
            Object oldValue = null;
            if (isExtractOldValueForEditor()) {
                oldValue = map.get(convertedMapKey);
            }
            // Pass full property name and old value in here, since we want full
            // conversion ability for map values.
            // 解析map类型属性的value值
            Object convertedMapValue = convertIfNecessary(tokens.canonicalName, oldValue, pv.getValue(),
                    mapValueType, ph.nested(tokens.keys.length));
            // 将解析后的key和value值赋值给map
            map.put(convertedMapKey, convertedMapValue);
        }

        else {
            throw new InvalidPropertyException(getRootClass(), this.nestedPath + tokens.canonicalName,
                    "Property referenced in indexed property path '" + tokens.canonicalName +
                    "' is neither an array nor a List nor a Map; returned value was [" + propValue + "]");
        }
    }

    private Object getPropertyHoldingValue(PropertyTokenHolder tokens) {
        // Apply indexes and map keys: fetch value for all keys but the last one.
        Assert.state(tokens.keys != null, "No token keys");
        PropertyTokenHolder getterTokens = new PropertyTokenHolder(tokens.actualName);
        getterTokens.canonicalName = tokens.canonicalName;
        getterTokens.keys = new String[tokens.keys.length - 1];
        System.arraycopy(tokens.keys, 0, getterTokens.keys, 0, tokens.keys.length - 1);

        Object propValue;
        try {
            // 获取属性值
            propValue = getPropertyValue(getterTokens);
        }
        catch (NotReadablePropertyException ex) {
            throw new NotWritablePropertyException(getRootClass(), this.nestedPath + tokens.canonicalName,
                    "Cannot access indexed value in property referenced " +
                    "in indexed property path '" + tokens.canonicalName + "'", ex);
        }

        if (propValue == null) {
            // null map value case
            if (isAutoGrowNestedPaths()) {
                int lastKeyIndex = tokens.canonicalName.lastIndexOf('[');
                getterTokens.canonicalName = tokens.canonicalName.substring(0, lastKeyIndex);
                propValue = setDefaultValue(getterTokens);
            }
            else {
                throw new NullValueInNestedPathException(getRootClass(), this.nestedPath + tokens.canonicalName,
                        "Cannot access indexed value in property referenced " +
                        "in indexed property path '" + tokens.canonicalName + "': returned null");
            }
        }
        return propValue;
    }

    /**
     * 设置本地属性
     * @param tokens
     * @param pv
     */
    private void processLocalProperty(PropertyTokenHolder tokens, PropertyValue pv) {
        PropertyHandler ph = getLocalPropertyHandler(tokens.actualName);
        // PropertyHandler为null, 或者方法不可写的时候
        if (ph == null || !ph.isWritable()) {
            // 返回是否为可选值, 即在目标类上不存在相应的属性时将被忽略
            if (pv.isOptional()) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Ignoring optional value for property '" + tokens.actualName +
                            "' - property not found on bean class [" + getRootClass().getName() + "]");
                }
                return;
            }
            else {
                throw createNotWritablePropertyException(tokens.canonicalName);
            }
        }

        Object oldValue = null;
        try {
            Object originalValue = pv.getValue();
            Object valueToApply = originalValue;
            if (!Boolean.FALSE.equals(pv.conversionNecessary)) {
                if (pv.isConverted()) {
                    valueToApply = pv.getConvertedValue();
                }
                else {
                    if (isExtractOldValueForEditor() && ph.isReadable()) {
                        try {
                            oldValue = ph.getValue();
                        }
                        catch (Exception ex) {
                            if (ex instanceof PrivilegedActionException) {
                                ex = ((PrivilegedActionException) ex).getException();
                            }
                            if (logger.isDebugEnabled()) {
                                logger.debug("Could not read previous value of property '" +
                                        this.nestedPath + tokens.canonicalName + "'", ex);
                            }
                        }
                    }
                    valueToApply = convertForProperty(
                            tokens.canonicalName, oldValue, originalValue, ph.toTypeDescriptor());
                }
                pv.getOriginalPropertyValue().conversionNecessary = (valueToApply != originalValue);
            }
            // 设置属性
            ph.setValue(valueToApply);
        }
        catch (TypeMismatchException ex) {
            throw ex;
        }
        catch (InvocationTargetException ex) {
            PropertyChangeEvent propertyChangeEvent = new PropertyChangeEvent(
                    getRootInstance(), this.nestedPath + tokens.canonicalName, oldValue, pv.getValue());
            if (ex.getTargetException() instanceof ClassCastException) {
                throw new TypeMismatchException(propertyChangeEvent, ph.getPropertyType(), ex.getTargetException());
            }
            else {
                Throwable cause = ex.getTargetException();
                if (cause instanceof UndeclaredThrowableException) {
                    // May happen e.g. with Groovy-generated methods
                    cause = cause.getCause();
                }
                throw new MethodInvocationException(propertyChangeEvent, cause);
            }
        }
        catch (Exception ex) {
            PropertyChangeEvent pce = new PropertyChangeEvent(
                    getRootInstance(), this.nestedPath + tokens.canonicalName, oldValue, pv.getValue());
            throw new MethodInvocationException(pce, ex);
        }
    }
}

public class BeanWrapperImpl extends AbstractNestablePropertyAccessor implements BeanWrapper {
    private class BeanPropertyHandler extends PropertyHandler {
        @Override
        public void setValue(final @Nullable Object value) throws Exception {
            // 获取可写方法, 例如javaBean中的setter()方法
            final Method writeMethod = (this.pd instanceof GenericTypeAwarePropertyDescriptor ?
                    ((GenericTypeAwarePropertyDescriptor) this.pd).getWriteMethodForActualAccess() :
                    this.pd.getWriteMethod());
            if (System.getSecurityManager() != null) {
                // 安全设置
                AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                    ReflectionUtils.makeAccessible(writeMethod);
                    return null;
                });
                try {
                    AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () ->
                            writeMethod.invoke(getWrappedInstance(), value), acc);
                }
                catch (PrivilegedActionException ex) {
                    throw ex.getException();
                }
            }
            else {
                ReflectionUtils.makeAccessible(writeMethod);
                // 调用Method方法的invoke方法, 通过反射方法为bean设置值
                writeMethod.invoke(getWrappedInstance(), value);
            }
        }
    }
}

通过对上面注入依赖代码的分析,我们已经明白了SpringIOC容器是如何将属性的值注入到Bean实例对象中去的:

  • 对于集合类型的属性,将其属性值解析为目标类型的集合后直接赋值给属性.
  • 对于非集合类型的属性,大量使用了JDK的反射和内省机制,通过属性的getter方法(readerMethod)获取指定属性注入以前的值,同时调用属性的setter方法(writerMethod)为属性设置注入后的值

Bean属性赋值

至此Spring IOC容器对Bean定义资源文件的定位,载入、解析和依赖注入已经全部分析完毕,现在Spring IOC容器中管理了一系列靠依赖关系联系起来的Bean,程序不需要应用自己手动创建所需的对象,Spring IOC容器会在我们使用的时候自动为我们创建,并且为我们注入好相关的依赖,这就是Spring核心功能的控制反转和依赖注入的相关功能.

results matching ""

    No results matching ""