天天看点

Spring源码学习【四】依赖注入过程一、总览二、源码分析

目录

一、总览

二、源码分析

(一)getBean触发依赖注入

(1)getBean

(2)createBean

(3)createBeanInstance

(4)populateBean

(二)Bean的预实例化

一、总览

通过前面的分析,我们知道了IOC容器在初始化过程中建立了BeanDefinition的数据结构,接下来就需要进行依赖注入,处理Bean之间的依赖关系。

通常,我们可以通过lazy-init属性控制Bean的实例化(依赖注入)时机。

当lazy-init=true时,依赖注入会发生在第一次向容器获取Bean时(getBean);当lazy-init=false时,会在容器初始化的过程中将所有的singleton bean提前进行实例化和依赖注入,因此singleton bean的依赖注入是容器初始化过程的一部分,这也是我们常用的ApplicationContext的默认配置。

二、源码分析

(一)getBean触发依赖注入

(1)getBean

getBean方法定义在BeanFactory接口中,以DefaultListableBeanFactory为例,其基类AbstractBeanFactory中实现了getBean方法,代码如下:

public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {

    ...
    /**
     * 向容器索要Bean,触发Bean的依赖注入
     */
    @Override
    public Object getBean(String name) throws BeansException {
        return doGetBean(name, null, null, false);
    }

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

        final String beanName = transformedBeanName(name);
        Object bean;

        // 首先检查是否存在缓存的singleton bean
        // 这里会涉及到单例缓存、提前曝光单例缓存和单例工厂缓存,后续会进一步解析这部分
        Object sharedInstance = getSingleton(beanName);
        if (sharedInstance != null && args == null) {
            if (logger.isDebugEnabled()) {
                if (isSingletonCurrentlyInCreation(beanName)) {
                    logger.debug("Returning eagerly cached instance of singleton bean '" + beanName + "' that is not fully initialized yet - a consequence of a circular reference");
                } else {
                    logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
                }
            }
            // 如果sharedInstance是FactoryBean,则返回其生产的Bean
            // 否则返回NullBean或sharedInstance本身
            bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
        } else {
            // 如果bean正在创建中则获取失败
            if (isPrototypeCurrentlyInCreation(beanName)) {
                throw new BeanCurrentlyInCreationException(beanName);
            }
            // 检查当前BeanFactory中是否存在以beanName为名的BeanDefinition
            // 如果当前BeanFactory中没有,则会顺着其父BeanFactory查找
            BeanFactory parentBeanFactory = getParentBeanFactory();
            // 这里的containsBeanDefinition是一个模板方法,由DefaultListableBeanFactory实现
            // 即在存储BeanDefinition的Map中查找是否存在
            if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
                // 当前BeanFactory未找到,开始在父BeanFactory中查找
                String nameToLookup = originalBeanName(name);
                if (parentBeanFactory instanceof AbstractBeanFactory) {
                    return ((AbstractBeanFactory) parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);
                } else if (args != null) {
                    return (T) parentBeanFactory.getBean(nameToLookup, args);
                } else {
                    return parentBeanFactory.getBean(nameToLookup, requiredType);
                }
            }
            if (!typeCheckOnly) {
                markBeanAsCreated(beanName);
            }
            try {
                // 根据beanName获取BeanFactory中的BeanDefinition
                // 这里的RootBeanDefinition代表着在继承关系下创建的BeanDefinition
                final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                checkMergedBeanDefinition(mbd, beanName, args);

                // 获得当前Bean依赖的所有Bean,通过 depends-on="xxx" 属性指定
                // 表示初始化当前Bean需要先初始化其依赖的xxx
                String[] dependsOn = mbd.getDependsOn();
                if (dependsOn != null) {
                    for (String dep : dependsOn) {
                        if (isDependent(beanName, dep)) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
                        }
                        registerDependentBean(dep, beanName);
                        try {
                           // 递归,直到取到没有depends-on的Bean
                           getBean(dep);
                        }
                        catch (NoSuchBeanDefinitionException ex) {
                            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "'" + beanName + "' depends on missing bean '" + dep + "'", ex);
                        }
                    }
                }
                // 创建bean实例
                if (mbd.isSingleton()) { // 创建singleton作用域Bean实例
                    sharedInstance = getSingleton(beanName, () -> {
                        try {
                            return createBean(beanName, mbd, args);
                        }
                        catch (BeansException ex) {
                            destroySingleton(beanName);
                            throw ex;
                        }
                    });
                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
                } else if (mbd.isPrototype()) { // 创建prototype作用域Bean实例
                    Object prototypeInstance = null;
                    try {
                        beforePrototypeCreation(beanName);
                        prototypeInstance = createBean(beanName, mbd, args);
                    }
                    finally {
                        afterPrototypeCreation(beanName);
                    }
                    bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
                } else { // 创建其他作用域Bean:request、session、global session
                    String scopeName = mbd.getScope();
                    final Scope scope = this.scopes.get(scopeName);
                    if (scope == null) {
                        throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
					}
                    try {
                        Object scopedInstance = scope.get(beanName, () -> {
                            beforePrototypeCreation(beanName);
                            try {
                                return createBean(beanName, mbd, args);
                            }
                            finally {
                                afterPrototypeCreation(beanName);
                            }
                        });
                        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;
            }
        } // end of else
        // 类型检查
        if (requiredType != null && !requiredType.isInstance(bean)) {
            try {
                // 类型转换
                T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
                if (convertedBean == null) {
                    throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
                }
                // 返回类型转换后的bean实例
                return convertedBean;
            }
            catch (TypeMismatchException ex) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Failed to convert bean '" + name + "' to required type '" + ClassUtils.getQualifiedName(requiredType) + "'", ex);
                }
                throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
            }
        }
        return (T) bean;
    }
}
           

(2)createBean

在前面的分析中,我们可以看到多处调用了createBean方法,这个方法是用来创建Bean实例的,并进行了一些其他处理。

createBean方法是一个模板方法,由其子类AbstractAutowireCapableBeanFactory实现,代码如下:

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {

    ...

    /**
     * 创建Bean
     */
    @Override
    protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {

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

        // 根据class属性或className解析beanClass
        Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
        if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
            mbdToUse = new RootBeanDefinition(mbd);
            mbdToUse.setBeanClass(resolvedClass);
        }

        // 对override属性(lookup-method、replace-method)进行处理
        // 会检测当前beanDefinition的class中是否是否包含相应方法,并将override方法标记为覆盖,防止进行重载参数检查
        try {
            mbdToUse.prepareMethodOverrides();
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", ex);
        }

        try {
            // 调用InstantiationAwareBeanPostProcessor
            // 允许在实例化前后进行处理
            // 如果返回值不为空,表示配置了InstantiationAwareBeanPostProcessor,并且修改了bean
            // 则返回一个代理,而不是bean实例
            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.isDebugEnabled()) {
                logger.debug("Finished creating instance of bean '" + beanName + "'");
            }
            return beanInstance;
        }
        catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
            throw ex;
        }
        catch (Throwable ex) {
            throw new BeanCreationException( mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
        }
    }

    /**
     * 真正开始创建Bean
     */
    protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) throws BeanCreationException {
        // 实例化bean
        BeanWrapper instanceWrapper = null;
        // 如果是单例bean,则先清除缓存
        if (mbd.isSingleton()) {
            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
        }
        // 若不存在缓存,则创建bean实例
        if (instanceWrapper == null) {
            instanceWrapper = createBeanInstance(beanName, mbd, args);
        }
        final Object bean = instanceWrapper.getWrappedInstance();
        Class<?> beanType = instanceWrapper.getWrappedClass();
        if (beanType != NullBean.class) {
            mbd.resolvedTargetType = beanType;
        }

        // 通过post-processors合并继承关系下的beanDefinition
        synchronized (mbd.postProcessingLock) {
            if (!mbd.postProcessed) {
                try {
                    applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                }
                catch (Throwable ex) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", ex);
                }
                mbd.postProcessed = true;
            }
        }

        // 提前曝光bean(利用缓存),用于支持循环bean的循环依赖
        boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName));
        if (earlySingletonExposure) {
            if (logger.isDebugEnabled()) {
                logger.debug("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");
            }
            // 通过匿名内部类添加单例工厂到缓存
            addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
        }

        // 初始化bean
        Object exposedObject = bean;
        try {
            // 这里开始进行依赖注入
            populateBean(beanName, mbd, instanceWrapper);
            // 初始化bean,执行init-method和后置处理器
            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);
            }
        }
        // 检查在提前曝光时,注入的bean是否为最终版本
        if (earlySingletonExposure) {
            Object earlySingletonReference = getSingleton(beanName, false);
            if (earlySingletonReference != null) {
                if (exposedObject == bean) {
                    exposedObject = earlySingletonReference;
                }
                else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
                    String[] dependentBeans = getDependentBeans(beanName);
                    Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
                    for (String dependentBean : dependentBeans) {
                        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.");
                    }
                }
            }
        }

        // 给Bean注册一些必要的销毁操作,当容器shutdown时执行
        try {
            registerDisposableBeanIfNecessary(beanName, bean, mbd);
        }
        catch (BeanDefinitionValidationException ex) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
        }
        // 返回Bean实例,这里已经完成了依赖注入
        return exposedObject;
    }

}
           

到这里,我们就已经得到依赖注入后的Bean实例了,这个过程看起来十分简单,但实际上有两个要点需要我们格外关注:其一,创建Bean实例(createBeanInstance);其二,进行依赖注入(populateBean),下面让我们继续分析。

(3)createBeanInstance

createBeanInstance通过适当的实例化策略来创建一个Bean实例,这里需要注意Spring5.0的新特性:通过设置Bean创建回调来覆盖工厂方法和构造函数。

在这个过程中,通过默认构造方法(无参构造)是基本的实例化策略,这个策略Spring的实现中提供了两种创建Bean的方式:其一,通过JVM反射创建Bean实例;其二,通过cgLib动态代理创建Bean实例。

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {

    ...

    /**
     * 创建Bean实例
     */
    protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
        // 确保Bean类可以实例化
        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());
        }

        // 5.0的新特性
        // doc注释:用作创建Bean的回调,设置该回调后会覆盖掉创建Bean的工厂方法和构造函数,
        // 但不影响依赖注入过程
        Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
        if (instanceSupplier != null) {
            return obtainFromSupplier(instanceSupplier, beanName);
        }

        // 使用工厂方法实例化Bean
        if (mbd.getFactoryMethodName() != null)  {
            return instantiateUsingFactoryMethod(beanName, mbd, args);
        }

        // 创建Bean时需要根据beanClass解析构造方法,并缓存在RootBeanDefinition中
        // 这里通过缓存直接进行处理,在创建相同Bean时不需要重复解析构造方法
        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) {
                return autowireConstructor(beanName, mbd, null, null);
            }
            else {
                return instantiateBean(beanName, mbd);
            }
        }

        // 使用构造函数实例化Bean
        Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
        if (ctors != null || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR || mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {
            // 有参构造函数
            return autowireConstructor(beanName, mbd, ctors, args);
        }

        // 默认构造函数
        // 这里共有两种方式创建Bean:其一,通过JVM反射;其二,通过cgLib的动态代理机制
        return instantiateBean(beanName, mbd);
    }

}
           

(4)populateBean

这里就是依赖注入的核心了,在这里,首先由InstantiationAwareBeanPostProcessors进行依赖注入前的处理,判断是否对Bean的Property进行注入,接下来先处理autowire的注入,这里的autowire指的是在配置文件中通过autowire="byName"或者autowire="byType"等属性配置的bean,最后处理Property属性注入,代码如下:

public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory implements AutowireCapableBeanFactory {

    ...

    /**
     * 依赖处理
     */
    protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
        if (bw == null) {
            if (mbd.hasPropertyValues()) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
            }
            else {
                // 不处理为空的Bean实例的依赖
                return;
            }
        }

        // 交由InstantiationAwareBeanPostProcessors处理是否对Bean实例进行依赖注入
        boolean continueWithPropertyPopulation = true;
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                if (bp instanceof InstantiationAwareBeanPostProcessor) {
                    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                    if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                        continueWithPropertyPopulation = false;
                        break;
                    }
                }
            }
        }

        if (!continueWithPropertyPopulation) {
            return;
        }

        PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);

        // 首先处理autowire依赖注入,根据Bean的名字或类型进行注入
        // 我们可以在配置文件中指定注入方式:autowire="byName"
        if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
            MutablePropertyValues newPvs = new MutablePropertyValues(pvs);

            // 按变量名注入
            if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
                autowireByName(beanName, mbd, bw, newPvs);
            }

            // 按类型注入
            if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
                autowireByType(beanName, mbd, bw, newPvs);
            }

            pvs = newPvs;
        }

        boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
        boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);

        if (hasInstAwareBpps || needsDepCheck) {
            if (pvs == null) {
                pvs = mbd.getPropertyValues();
            }
            PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
            // 在为Bean注入依赖前进行后置处理,比如检查@Required是否满足,添加或移除Property
            if (hasInstAwareBpps) {
                for (BeanPostProcessor bp : getBeanPostProcessors()) {
                    if (bp instanceof InstantiationAwareBeanPostProcessor) {
                        InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                        pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                        if (pvs == null) {
                            return;
                        }
                    }
                }
            }
            // 进行依赖检查
            if (needsDepCheck) {
                checkDependencies(beanName, mbd, filteredPds, pvs);
            }
        }

        // 对属性进行注入
        if (pvs != null) {
            applyPropertyValues(beanName, mbd, bw, pvs);
        }
    }

    /**
     * 注入Property
     */
    protected void applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) {
        if (pvs.isEmpty()) {
            return;
        }

        if (System.getSecurityManager() != null && bw instanceof BeanWrapperImpl) {
            ((BeanWrapperImpl) bw).setSecurityContext(getAccessControlContext());
        }

        // 注入的Property
        MutablePropertyValues mpvs = null;
        List<PropertyValue> original;

        // pvs是MutablePropertyValues实例,且可强制类型转换,则可以直接设置为注入的Property
        if (pvs instanceof MutablePropertyValues) {
            mpvs = (MutablePropertyValues) pvs;
            if (mpvs.isConverted()) {
                try {
                    bw.setPropertyValues(mpvs);
                    return;
                }
                catch (BeansException ex) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Error setting property values", ex);
                }
            }
            original = mpvs.getPropertyValueList();
        }
        else {
            original = Arrays.asList(pvs.getPropertyValues());
        }

        TypeConverter converter = getCustomTypeConverter();
        if (converter == null) {
            converter = bw;
        }

        // valueResolver用于解析BeanDefinition中的Property
        BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this, beanName, mbd, converter);

        // 创建一个深拷贝副本,这个副本持有的Property会被注入到Bean中
        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();
                // 利用valueResolver解析PropertyValue
                // TODO 具体的解析待后续分析
                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);
                }
                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();
        }

        // 将拷贝副本中的PropertyValues注入到Bean中
        try {
            bw.setPropertyValues(new MutablePropertyValues(deepCopy));
        }
        catch (BeansException ex) {
            throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Error setting property values", ex);
        }
    }

}
           

到这里,我们发现最终的依赖注入实际上调用了BeanWrapper接口的setPropertyValues方法,这个方法由AbstractPropertyAccessor实现,在这个方法中,取得了所有的属性,对每一个属性进行注入,代码如下:

public abstract class AbstractPropertyAccessor extends TypeConverterSupport implements ConfigurablePropertyAccessor {

    ...

    @Override
    public void setPropertyValues(PropertyValues pvs) throws BeansException {
        setPropertyValues(pvs, false, false);
    }

    @Override
    public void setPropertyValues(PropertyValues pvs, boolean ignoreUnknown, boolean ignoreInvalid) throws BeansException {
        List<PropertyAccessException> propertyAccessExceptions = null;
        // 取得属性
        List<PropertyValue> propertyValues = (pvs instanceof MutablePropertyValues ?  ((MutablePropertyValues) pvs).getPropertyValueList() : Arrays.asList(pvs.getPropertyValues()));
        for (PropertyValue pv : propertyValues) {
            try {
                // 注入属性
                setPropertyValue(pv);
            }
            catch (NotWritablePropertyException ex) {
                if (!ignoreUnknown) {
                    throw ex;
                }
            }
            catch (NullValueInNestedPathException ex) {
                if (!ignoreInvalid) {
                    throw ex;
                }
            }
            catch (PropertyAccessException ex) {
                if (propertyAccessExceptions == null) {
                    propertyAccessExceptions = new LinkedList<>();
                }
                propertyAccessExceptions.add(ex);
            }
        }

        if (propertyAccessExceptions != null) {
            PropertyAccessException[] paeArray = propertyAccessExceptions.toArray(new PropertyAccessException[0]);
            throw new PropertyBatchUpdateException(paeArray);
        }
    }

    @Override
    public void setPropertyValue(PropertyValue pv) throws BeansException {
        setPropertyValue(pv.getName(), pv.getValue());
    }

    @Override
    public abstract void setPropertyValue(String propertyName, @Nullable Object value) throws BeansException;

}
           

这里的setPropertyValue(String, Object)是一个模板方法,具体的实现在其子类AbstractNestablePropertyAccessor中,这是4.2版本加入的新特性,在更早的版本中,setProperty(String,Object)方法是由BeanWrapperImpl实现的,在新版本的实现中,BeanWrapperImpl继承了AbstractNestablePropertyAccessor,但具体的实现原理还是一样的,AbstractNestablePropertyAccessor代码如下:

public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyAccessor {

    ...

    @Override
    public void setPropertyValue(String propertyName, @Nullable Object value) throws BeansException {
        AbstractNestablePropertyAccessor nestedPa;
        try {
            // 取得属性访问器
            nestedPa = getPropertyAccessorForPropertyPath(propertyName);
        }
        catch (NotReadablePropertyException ex) {
            throw new NotWritablePropertyException(getRootClass(), this.nestedPath + propertyName, "Nested property in path '" + propertyName + "' does not exist", ex);
        }
        // 将propertyName解析为PropertyTokenHolder,根据keys是否为空分为集合和非集合类型
        PropertyTokenHolder tokens = getPropertyNameTokens(getFinalPath(nestedPa, propertyName));
        nestedPa.setPropertyValue(tokens, new PropertyValue(propertyName, value));
    }

    /**
     * 通过递归返回一个嵌套属性路径的属性访问器
     */
    protected AbstractNestablePropertyAccessor getPropertyAccessorForPropertyPath(String propertyPath) {
        // 查找第一个嵌套属性路径分隔符,即".",的位置
        int pos = PropertyAccessorUtils.getFirstNestedPropertySeparatorIndex(propertyPath);
        // 包含分隔符
        if (pos > -1) {
            String nestedProperty = propertyPath.substring(0, pos);
            String nestedPath = propertyPath.substring(pos + 1);
            AbstractNestablePropertyAccessor nestedPa = getNestedPropertyAccessor(nestedProperty);
            // 递归
            return nestedPa.getPropertyAccessorForPropertyPath(nestedPath);
        }
        // 不包含分隔符,即找到了嵌套属性路径中最底层的属性
        // 比如嵌套的a.b,则会找到b这一个属性访问器
        else {
            return this;
        }
    }

    /**
     * 解析propertyName
     */
    private PropertyTokenHolder getPropertyNameTokens(String propertyName) {
        String actualName = null;
        List<String> keys = new ArrayList<>(2);
        int searchIndex = 0;
        while (searchIndex != -1) {
            // 查找"["位置
            int keyStart = propertyName.indexOf(PROPERTY_KEY_PREFIX, searchIndex);
            searchIndex = -1;
            if (keyStart != -1) {
                // 查找"]"位置
                int keyEnd = propertyName.indexOf(PROPERTY_KEY_SUFFIX, keyStart + PROPERTY_KEY_PREFIX.length());
                if (keyEnd != -1) {
                    if (actualName == null) {
                        // 截取属性名
                        actualName = propertyName.substring(0, keyStart);
                    }
                    // 这里的key是"["和"]"之间的内容,比如a[3],那么key就是3
                    String key = propertyName.substring(keyStart + PROPERTY_KEY_PREFIX.length(), keyEnd);
                    // 去掉key前后的单引号or双引号
                    if (key.length() > 1 && (key.startsWith("'") && key.endsWith("'")) || (key.startsWith("\"") && key.endsWith("\""))) {
                        key = key.substring(1, key.length() - 1);
                    }
                    keys.add(key);
                    searchIndex = keyEnd + PROPERTY_KEY_SUFFIX.length();
                }
            }
        }
        // 根据属性名创建PropertyTokenHolder
        PropertyTokenHolder tokens = new PropertyTokenHolder(actualName != null ? actualName : propertyName);
        if (!keys.isEmpty()) {
            tokens.canonicalName += PROPERTY_KEY_PREFIX + StringUtils.collectionToDelimitedString(keys, PROPERTY_KEY_SUFFIX + PROPERTY_KEY_PREFIX) + PROPERTY_KEY_SUFFIX;
            tokens.keys = StringUtils.toStringArray(keys);
        }
        return tokens;
    }

}
           

这段代码里我们可以看到,首先在嵌套属性中取得嵌套最底层的属性的访问器,然后将对属性名进行解析,将解析结果封装在PropertyTokenHolder中。

这里需要对嵌套属性和PropertyTokenHolder做一个解释,在刚开始看源码的时候就卡在了这里,一直没有搞懂这种解析发生在什么情况下,下面我们来对这两个概念做一下简单的解析:

首先,嵌套属性,例如我们在Spring配置文件中有如下配置:

<beans>
    <bean id="a" class="greedystar.entity.A" lazy-init="true">
        <property name="name" value="Alvin"/>
        <property name="id" value="123"/>
    </bean>

    <bean id="b" class="greedystar.entity.B" lazy-init="true">
        <property name="a" ref="a"/>
        <property name="a.name" value="李四"/>
    </bean>
</beans>
           

这里的 <property name="a.name" value="李四"/> 就是嵌套属性,代码中通过递归取得嵌套最底层的属性的访问器,也就是a.name中name属性的访问器。

其次,PropertyTokenHolder,例如我们在Spring配置文件中有如下配置:

<beans>
    <bean id="a" class="greedystar.entity.A" lazy-init="true">
        <property name="name" value="Alvin"/>
        <property name="id" value="123"/>
        <property name="roles">
            <list>
                <value>USER</value>
                <value>ADMIN</value>
            </list>
        </property>
    </bean>

    <bean id="b" class="greedystar.entity.B" lazy-init="true">
        <property name="a" ref="a"/>
        <property name="a.name" value="李四"/>
        <property name="a.roles[0]" value="USER1"/>
        <property name="a.roles[1]" value="ADMIN1"/>
    </bean>
</beans>
           

当解析到a.roles[0]这个属性时,会把这个属性名解析到PropertyTokenHolder对象中,这个对象的属性值如下:

Spring源码学习【四】依赖注入过程一、总览二、源码分析

可以看到,这里的keys对应的就是访问集合属性时的索引值,当keys不为空时认为这个属性为集合取值属性,为空则不为集合取值取值属性,集合取值属性这个名字是我为了区别于普通的注入集合属性而随意写下的,各位对这里有所区别就好。

OK,对嵌套属性和集合取值属性有所了解后,我们继续回到AbstractNestablePropertyAccessor这个类中,通过上面的分析,我们已经取得了PropertyTokenHolder对象,下面将通过该对象进行属性的注入,代码如下:

public abstract class AbstractNestablePropertyAccessor extends AbstractPropertyAccessor {

    ...

    protected void setPropertyValue(PropertyTokenHolder tokens, PropertyValue pv) throws BeansException {
        if (tokens.keys != null) {
            // 集合取值属性,key的值代表取值的索引
            processKeyedProperty(tokens, pv);
        }
        else { // 非集合取值属性
            processLocalProperty(tokens, pv);
        }
    }
    
    /**
     * 集合取值属性注入
     */
    private void processKeyedProperty(PropertyTokenHolder tokens, PropertyValue pv) {
        // 根据属性名取得要注入的属性,这里使用了Java的内省机制,也就是通过setter和getter存取属性
        Object propValue = getPropertyHoldingValue(tokens);
        // 这里的PropertyHandler是对PropertyDescriptor的封装,具体的实现在BeanWrapperImpl中
        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];
        //这里处理数组类型的集合取值属性
        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);
                    propValue = getPropertyValue(tokens.actualName);
                }
                // 将转换后的值set到索引指定的位置
                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和MAP,基本属于同一个套路,这里就不把代码贴出来了
        else if (propValue instanceof List) {

        } else if (propValue instanceof Map) {

        }

        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 void processLocalProperty(PropertyTokenHolder tokens, PropertyValue pv) {
        // 取得PropertyHandler,用于后续使用内省机制
        PropertyHandler ph = getLocalPropertyHandler(tokens.actualName);
        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);
            }
            // 通过Java内省机制set新的属性值,setValue方法的具体实现在BeanWrapperImpl中
            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);
        }
    }

}
           

到这里,我们发现最终调用了BeanWrapperImpl的setValue方法,通过Java的内省机制将Bean所依赖的属性注入到Bean中,这样Bean之间的依赖关系就处理完成了,接下来这些Bean就可以被我们直接使用了。

(二)Bean的预实例化

我们知道当为Bean配置了lazy-init=false属性时,IOC容器会在初始化的时候对Bean进行预实例化,这时将会提前触发Bean的依赖注入过程,我们回到AbstractApplicationContext的refresh方法中,这里是IOC容器初始化的入口,在这个方法中我们可以看到调用了finishBeanFactoryInitialization方法,这个方法将会对非延迟加载的单例Bean进行预实例化,代码如下:

public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {

    @Override
    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            ...

            // 预实例化非延迟加载的单例Bean
            finishBeanFactoryInitialization(beanFactory);

            ...		
        }
    }

    protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        ...

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

    }

}
           

这里调用了ConfigurableListableBeanFactory接口的preInstantiateSingletons()方法,具体由DefaultListableBeanFactory实现,代码如下:

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {

    ...

    @Override
    public void preInstantiateSingletons() throws BeansException {
        if (this.logger.isDebugEnabled()) {
            this.logger.debug("Pre-instantiating singletons in " + this);
        }

        // 所有Bean的名称
        List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

        for (String beanName : beanNames) {
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            // 将非延迟加载的单例Bean预实例化
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                if (isFactoryBean(beanName)) {
                    Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                    if (bean instanceof FactoryBean) {
                        final FactoryBean<?> factory = (FactoryBean<?>) bean;
                        boolean isEagerInit;
                        if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                            isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit, getAccessControlContext());
                        }
                        else {
                            isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factory).isEagerInit());
                        }
                        if (isEagerInit) {
                            // 触发依赖注入
                            getBean(beanName);
                        }
                    }
                }
                else {
                    // 触发依赖注入
                    getBean(beanName);
                }
            }
        }

        // 触发单例实例化后的回调方法
        for (String beanName : beanNames) {
            Object singletonInstance = getSingleton(beanName);
            if (singletonInstance instanceof SmartInitializingSingleton) {
                final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
                if (System.getSecurityManager() != null) {
                    AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                        smartSingleton.afterSingletonsInstantiated();
                        return null;
                    }, getAccessControlContext());
                }
                else {
                    smartSingleton.afterSingletonsInstantiated();
                }
            }
        }
    }

}
           

分析到这里我们发现,在预实例化的过程中调用了getBean方法来触发Bean的依赖注入,后续的处理就与前面分析的过程一样了,通过一系列的处理,Bean的预实例化过程就完成了。

继续阅读