Spring源码解析(十)-填充bean属性

Spring版本

5.2.5.RELEASE

参考

《芋道源码》

源码解读

《Spring源码解析(八)-创建单例bean》中,创建bean实例的方法doCreateBean中调用了populateBean方法来填充bean属性,下面浅析一下具体源码

1. AbstractAutowireCapableBeanFactory#populateBean

    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 {
                // Skip property population phase for null instance.
                return;
            }
        }

        // 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.
        // 给BeanPostProcessor一个机会在bean填充属性之前改变bean
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                if (bp instanceof InstantiationAwareBeanPostProcessor) {
                    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                    if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                        return;
                    }
                }
            }
        }

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

        int resolvedAutowireMode = mbd.getResolvedAutowireMode();
        if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
            MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
            // Add property values based on autowire by name if applicable.
            if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
                autowireByName(beanName, mbd, bw, newPvs);
            }
            // Add property values based on autowire by type if applicable.
            if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
                autowireByType(beanName, mbd, bw, newPvs);
            }
            pvs = newPvs;
        }

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

        PropertyDescriptor[] filteredPds = null;
        if (hasInstAwareBpps) {
            if (pvs == null) {
                pvs = mbd.getPropertyValues();
            }
            for (BeanPostProcessor bp : getBeanPostProcessors()) {
                if (bp instanceof InstantiationAwareBeanPostProcessor) {
                    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                    // postProcessProperties:在应用属性到bean之前,对属性做一个post process处理
                    PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
                    if (pvsToUse == null) {
                        if (filteredPds == null) {
                            // 过滤出所有需要进行依赖检查的属性编辑器
                            filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                        }
                        // 加上filteredPds进行post process处理
                        pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                        if (pvsToUse == null) {
                            return;
                        }
                    }
                    pvs = pvsToUse;
                }
            }
        }
        // 检查依赖
        if (needsDepCheck) {
            if (filteredPds == null) {
                filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
            }
            // 属性值设置最终是通过set方法进行,所以这里对要求进行检查的属性进行了检查,检查内容主要有俩项
            // 1、是否有set方法
            // 2、pvs是否包含filteredPds中的每个元素
            checkDependencies(beanName, mbd, filteredPds, pvs);
        }

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

核心流程大致可以分为:

  • 在填充属性之前,给InstantiationAwareBeanPostProcessor一个机会改变属性(关于BeanPostProcessor,可查阅《Spring源码解析(十四)-BeanPostProcessor》
  • BeanDefinition中获取属性值pvs,如果注入模式是AUTOWIRE_BY_NAME或者AUTOWIRE_BY_TYPE,则分别通过autowireByNameautowireByType来获取属性值newPvs,并覆盖pvs
  • 再次给BeanPostProcessors机会改变属性,并将改变后的属性值赋值到pvs
  • 检查依赖,主要是为下一步应用属性到bean中做检查
  • 应用属性到bean中

下面浅析较为复杂的子流程

2. InstantiationAwareBeanPostProcessor

该类的源码注释提供了这么一段说明:

/**
 * Subinterface of {@link BeanPostProcessor} that adds a before-instantiation callback,
 * and a callback after instantiation but before explicit properties are set or
 * autowiring occurs.
 */

简单说来,就是这是一个BeanPostProcessor的子接口,增加了实例化之前的回调功能和实例化之后但设置精确属性或者自动注入发生之前的回调。
所以,在populateBean中,在设置精确属性和自动注入之前,先判断是否包含InstantiationAwareBeanPostProcessor

hasInstantiationAwareBeanPostProcessors()

如果包含,调用postProcessAfterInstantiation方法:

    default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        return true;
    }

该方法默认返回true,在populateBean中,返回false的情况下会中断填充属性流程

3. AbstractAutowireCapableBeanFactory#autowireByName

    protected void autowireByName(
            String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

        // 获取bean中的非简单属性
        String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
        for (String propertyName : propertyNames) {
            if (containsBean(propertyName)) {
                // 获取bean实例
                Object bean = getBean(propertyName);
                pvs.add(propertyName, bean);
                // 注册依赖关系
                registerDependentBean(propertyName, beanName);
                if (logger.isTraceEnabled()) {
                    logger.trace("Added autowiring by name from bean name '" + beanName +
                            "' via property '" + propertyName + "' to bean named '" + propertyName + "'");
                }
            }
            else {
                if (logger.isTraceEnabled()) {
                    logger.trace("Not autowiring property '" + propertyName + "' of bean '" + beanName +
                            "' by name: no matching bean found");
                }
            }
        }
    }

3.1 AbstractAutowireCapableBeanFactory#unsatisfiedNonSimpleProperties

首先获取到非简单属性,判断简单属性的核心代码如下:

    protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) {
        Set<String> result = new TreeSet<>();
        PropertyValues pvs = mbd.getPropertyValues();
        PropertyDescriptor[] pds = bw.getPropertyDescriptors();
        for (PropertyDescriptor pd : pds) {
            if (pd.getWriteMethod() != null && !isExcludedFromDependencyCheck(pd) && !pvs.contains(pd.getName()) &&
                    !BeanUtils.isSimpleProperty(pd.getPropertyType())) {
                result.add(pd.getName());
            }
        }
        return StringUtils.toStringArray(result);
    }
    public static boolean isSimpleProperty(Class<?> type) {
        Assert.notNull(type, "'type' must not be null");
        return isSimpleValueType(type) || (type.isArray() && isSimpleValueType(type.getComponentType()));
    }
    public static boolean isSimpleValueType(Class<?> type) {
        return (Void.class != type && void.class != type &&
                (ClassUtils.isPrimitiveOrWrapper(type) ||
                Enum.class.isAssignableFrom(type) ||
                CharSequence.class.isAssignableFrom(type) ||
                Number.class.isAssignableFrom(type) ||
                Date.class.isAssignableFrom(type) ||
                Temporal.class.isAssignableFrom(type) ||
                URI.class == type ||
                URL.class == type ||
                Locale.class == type ||
                Class.class == type));
    }

可见,简单属性包含以下数据类型及其对应的数组:

  • 基本类型及其包装类型
  • 枚举
  • 字符串
  • Number
  • Date
  • Temporal
  • URI
  • URL
  • Locale
  • Class

3.2 AbstractAutowireCapableBeanFactory#containsBean

对3.1中获取到对简单属性集合进行遍历,通过containsBean确认已经被解析成bean实例或者已经解析好BeanDefinition,如果本类判断不出来,在交由parentBeanFactory递归判断

    @Override
    public boolean containsBean(String name) {
        String beanName = transformedBeanName(name);
        if (containsSingleton(beanName) || containsBeanDefinition(beanName)) {
            return (!BeanFactoryUtils.isFactoryDereference(name) || isFactoryBean(name));
        }
        // Not found -> check parent.
        BeanFactory parentBeanFactory = getParentBeanFactory();
        return (parentBeanFactory != null && parentBeanFactory.containsBean(originalBeanName(name)));
    }

3.2.1 AbstractAutowireCapableBeanFactory#containsSingleton:

    @Override
    public boolean containsSingleton(String beanName) {
        return this.singletonObjects.containsKey(beanName);
    }

singletonObjects用于存放已经实例化的<beanName, bean实例>,具体可看 《Spring源码解析(八)-创建单例bean》

3.2.2 AbstractAutowireCapableBeanFactory#containsBeanDefinition

    @Override
    public boolean containsBeanDefinition(String beanName) {
        Assert.notNull(beanName, "Bean name must not be null");
        return this.beanDefinitionMap.containsKey(beanName);
    }

beanDefinitionMap用于存放已经解析完毕的<beanName,beanDefinition>,具体可看Spring源码解析(六)-解析bean标签

3.3 AbstractAutowireCapableBeanFactory#getBean

如果containsBean中条件成立,则通过getBean从缓存获取bean实例,或者递归创建bean实例,之后将bean实例加入pvs

3.4 AbstractAutowireCapableBeanFactory#registerDependentBean

通过registerDependentBean进行依赖注册:

    public void registerDependentBean(String beanName, String dependentBeanName) {
        String canonicalName = canonicalName(beanName);

        synchronized (this.dependentBeanMap) {
            Set<String> dependentBeans =
                    this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));
            if (!dependentBeans.add(dependentBeanName)) {
                return;
            }
        }

        synchronized (this.dependenciesForBeanMap) {
            Set<String> dependenciesForBean =
                    this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
            dependenciesForBean.add(canonicalName);
        }
    }

逻辑就是往dependentBeanMapdependenciesForBeanMap写入映射关系

4. AbstractAutowireCapableBeanFactory#autowireByType

相对于autowireByNameautowireByType的流程无疑长了很多,简直是看到绝望的地步,断断续续花了将近一周,才略懂一二

    protected void autowireByType(
            String beanName, AbstractBeanDefinition mbd, BeanWrapper bw, MutablePropertyValues pvs) {

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

        Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
        // 获取bean中的非简单属性
        String[] propertyNames = unsatisfiedNonSimpleProperties(mbd, bw);
        for (String propertyName : propertyNames) {
            try {
                // 通过propertyName获取持有该属性描述信息的PropertyDescriptor对象
                PropertyDescriptor pd = bw.getPropertyDescriptor(propertyName);
                // Don't try autowiring by type for type Object: never makes sense,
                // even if it technically is a unsatisfied, non-simple property.
                // 如果属性是Object,直接跳过,Object类型没有意义
                if (Object.class != pd.getPropertyType()) {
                    // 获取set方法
                    MethodParameter methodParam = BeanUtils.getWriteMethodParameter(pd);
                    // Do not allow eager init for type matching in case of a prioritized post-processor.
                    // 对于PriorityOrdered的bean,不允许即刻初始化,因为PriorityOrdered意味着有优先级和顺序的区分
                    boolean eager = !(bw.getWrappedInstance() instanceof PriorityOrdered);
                    DependencyDescriptor desc = new AutowireByTypeDependencyDescriptor(methodParam, eager);
                    Object autowiredArgument = resolveDependency(desc, beanName, autowiredBeanNames, converter);
                    if (autowiredArgument != null) {
                        pvs.add(propertyName, autowiredArgument);
                    }
                    for (String autowiredBeanName : autowiredBeanNames) {
                        // 注册依赖关系
                        registerDependentBean(autowiredBeanName, beanName);
                        if (logger.isTraceEnabled()) {
                            logger.trace("Autowiring by type from bean name '" + beanName + "' via property '" +
                                    propertyName + "' to bean named '" + autowiredBeanName + "'");
                        }
                    }
                    autowiredBeanNames.clear();
                }
            }
            catch (BeansException ex) {
                throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, propertyName, ex);
            }
        }
    }

autowireByName相同,先获取到非简单属性集合,遍历:

  • 获取属性描述符pd
  • 通过属性描述符pd和依赖描述符desc解析出bean实例autowiredArgument,并且在解析过程中获得autowiredArgument依赖到bean实例名称集合autowiredBeanNames
  • autowiredBeanNamesbeanName进行依赖关系注册

核心功能点在于resolveDependency方法

4.1 DefaultListableBeanFactory#resolveDependency

    @Override
    @Nullable
    public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
            @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {

        descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
        if (Optional.class == descriptor.getDependencyType()) {
            // 对Optional的处理,内部依旧调用了doResolveDependency
            return createOptionalDependency(descriptor, requestingBeanName);
        }
        else if (ObjectFactory.class == descriptor.getDependencyType() ||
                ObjectProvider.class == descriptor.getDependencyType()) {
            return new DependencyObjectProvider(descriptor, requestingBeanName);
        }
        else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
            return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
        }
        else {
            // 为实际依赖关系目标的延迟解析构建代理
            // 默认实现返回 null
            Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
                    descriptor, requestingBeanName);
            if (result == null) {
                result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
            }
            return result;
        }
    }

该方法主要针对各种类型做了对应的处理,这里我们主要关心核心方法doResolveDependency

4.2 DefaultListableBeanFactory#doResolveDependency

    @Nullable
    public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
            @Nullable Set<String> autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {

        InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
        try {
            // 针对给定的工厂给定一个快捷实现的方式,例如考虑一些预先解析的信息
            Object shortcut = descriptor.resolveShortcut(this);
            if (shortcut != null) {
                return shortcut;
            }

            Class<?> type = descriptor.getDependencyType();

            // 支持@Value,此处value为@Value注解内的值
            Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
            if (value != null) {
                if (value instanceof String) {
                    // 解析实际嵌入的值,即将@Value中的值解析成配置的值
                    String strVal = resolveEmbeddedValue((String) value);
                    BeanDefinition bd = (beanName != null && containsBean(beanName) ?
                            getMergedBeanDefinition(beanName) : null);
                    // 如果是SPEL表达式,进行SPEL表达式的解析
                    value = evaluateBeanDefinitionString(strVal, bd);
                }
                TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
                try {
                    // 如果有必要,进行类型转换
                    return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
                }
                catch (UnsupportedOperationException ex) {
                    // A custom TypeConverter which does not support TypeDescriptor resolution...
                    return (descriptor.getField() != null ?
                            converter.convertIfNecessary(value, type, descriptor.getField()) :
                            converter.convertIfNecessary(value, type, descriptor.getMethodParameter()));
                }
            }

            // 解析数组、Collection、Map等类型的复合bean
            Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
            if (multipleBeans != null) {
                return multipleBeans;
            }

            // 获取匹配的bean集合
            Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
            if (matchingBeans.isEmpty()) {
                // 没有匹配的实例,但是Autowire的required为true,抛出异常
                if (isRequired(descriptor)) {
                    raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
                }
                return null;
            }

            String autowiredBeanName;
            Object instanceCandidate;

            if (matchingBeans.size() > 1) {
                // 匹配集合大于1,获取最合适的bean实例
                autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
                if (autowiredBeanName == null) {
                    // 没有匹配到合适的bean实例
                    if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
                        // Autowire的required为true,且不是multipleBean,交由descriptor解析(该方法默认抛出异常)
                        return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
                    }
                    else {
                        // In case of an optional Collection/Map, silently ignore a non-unique case:
                        // possibly it was meant to be an empty collection of multiple regular beans
                        // (before 4.3 in particular when we didn't even look for collection beans).
                        return null;
                    }
                }
                instanceCandidate = matchingBeans.get(autowiredBeanName);
            }
            else {
                // We have exactly one match.
                // 刚好1个
                Map.Entry<String, Object> entry = matchingBeans.entrySet().iterator().next();
                autowiredBeanName = entry.getKey();
                instanceCandidate = entry.getValue();
            }

            if (autowiredBeanNames != null) {
                autowiredBeanNames.add(autowiredBeanName);
            }
            if (instanceCandidate instanceof Class) {
                // 前面获取到的instanceCandidate已经是一个bean实例了,为何需要再度通过getBean获取bean实例?
                instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
            }
            Object result = instanceCandidate;
            if (result instanceof NullBean) {
                if (isRequired(descriptor)) {
                    raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
                }
                result = null;
            }
            if (!ClassUtils.isAssignableValue(type, result)) {
                throw new BeanNotOfRequiredTypeException(autowiredBeanName, type, instanceCandidate.getClass());
            }
            return result;
        }
        finally {
            ConstructorResolver.setCurrentInjectionPoint(previousInjectionPoint);
        }
    }

依旧是切分成几个部分来分析:

  • 通过resolveShortcut来为给定的工厂提供一个快捷解析的方式
  • 解析@Value注解
  • 解析数组、Collection、Map等类型的复合bean
  • 查找合适的候选bean集合matchingBeans,并从matchingBeans中确定最合适的bean实例

这里存在一个疑问,经过前面的步骤,matchingBeans中存放的已经是实例后的bean,不明白为啥还需要descriptor.resolveCandidate(autowiredBeanName, type, this);,该方法底层也是调用getBean,看起来并没有什么意义

4.2.1 DefaultListableBeanFactory#findAutowireCandidates

    protected Map<String, Object> findAutowireCandidates(
            @Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {

        // 获取到符合类型要求的候选bean名称集合
        String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                this, requiredType, true, descriptor.isEager());
        Map<String, Object> result = new LinkedHashMap<>(candidateNames.length);
        // 从resolvableDependencies解析出符合requiredType的bean,并解析成对应实例
        // 通过resolvableDependencies的put调用及debug可以看到,resolvableDependencies的值一般为:
        // BeanFactory.class -> instance
        // ResourceLoader.class -> instance
        // ApplicationEventPublisher.class -> instance
        // ApplicationContext.class -> instance
        for (Map.Entry<Class<?>, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {
            Class<?> autowiringType = classObjectEntry.getKey();
            // 符合requiredType类型,或者派生自requiredType
            if (autowiringType.isAssignableFrom(requiredType)) {
                Object autowiringValue = classObjectEntry.getValue();
                // 解析出bean实例
                autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
                // 解析出的bean实例是requiredType的实例
                if (requiredType.isInstance(autowiringValue)) {
                    // 加入结果集
                    result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
                    break;
                }
            }
        }
        // 从候选者中进行筛选
        for (String candidate : candidateNames) {
            // 筛选条件
            // 1、不能是自我引用
            // 2、candidate对应的beanDefinition中是否设置autowire-candidate为true
            if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
                addCandidateEntry(result, candidate, descriptor, requiredType);
            }
        }
        if (result.isEmpty()) {
            // 如果依旧没找到,执行降级匹配
            boolean multiple = indicatesMultipleBeans(requiredType);
            // Consider fallback matches if the first pass failed to find anything...
            DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();
            for (String candidate : candidateNames) {
                if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, fallbackDescriptor) &&
                        (!multiple || getAutowireCandidateResolver().hasQualifier(descriptor))) {
                    addCandidateEntry(result, candidate, descriptor, requiredType);
                }
            }
            if (result.isEmpty() && !multiple) {
                // Consider self references as a final pass...
                // but in the case of a dependency collection, not the very same bean itself.
                for (String candidate : candidateNames) {
                    if (isSelfReference(beanName, candidate) &&
                            (!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) &&
                            isAutowireCandidate(candidate, fallbackDescriptor)) {
                        addCandidateEntry(result, candidate, descriptor, requiredType);
                    }
                }
            }
        }
        return result;
    }
  • 筛选出候选bean集合candidateNames
  • resolvableDependencies筛选出合适的数据加入结果集result中,resolvableDependencies比较陌生,从debug来看,预置这四个数据:
    • BeanFactory.class -> instance
    • ResourceLoader.class -> instance
    • ApplicationEventPublisher.class -> instance
    • ApplicationContext.class -> instance
resolvableDependencies
  • candidateNames筛选出合适的数据加入结果集result
  • 如果经过上述步骤,结果集result依旧为空,执行降级策略的处理

4.2.2 DefaultListableBeanFactory#determineAutowireCandidate

matchingBeans数量大于1时,会进入该方法来决定使用哪个候选值

    @Nullable
    protected String determineAutowireCandidate(Map<String, Object> candidates, DependencyDescriptor descriptor) {
        Class<?> requiredType = descriptor.getDependencyType();
        // 获取在BeanDefinition中被标记为primary的bean
        // <bean id="valueBean" class="com.kungyu.custom.element.ValueBean" primary="true"/>
        String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);
        if (primaryCandidate != null) {
            return primaryCandidate;
        }
        // 获取优先级最高的bean
        String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);
        if (priorityCandidate != null) {
            return priorityCandidate;
        }
        // Fallback
        // 如果上述均不满足,从resolvableDependencies中返回第一个匹配的bean
        for (Map.Entry<String, Object> entry : candidates.entrySet()) {
            String candidateName = entry.getKey();
            Object beanInstance = entry.getValue();
            if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) ||
                    matchesBeanName(candidateName, descriptor.getDependencyName())) {
                return candidateName;
            }
        }
        return null;
    }

该方法用于从candidates挑选出最合适的bean名称:

  • 如果bean设置了primary属性,且值为true,返回该候选值
  • 如果bean设置了优先级,返回优先级最高的候选值
  • 如果上述均不满足,从resolvableDependencies中获取到匹配名称的第一个候选值

5. AbstractAutowireCapableBeanFactory#checkDependencies

    protected void checkDependencies(
            String beanName, AbstractBeanDefinition mbd, PropertyDescriptor[] pds, @Nullable PropertyValues pvs)
            throws UnsatisfiedDependencyException {

        int dependencyCheck = mbd.getDependencyCheck();
        for (PropertyDescriptor pd : pds) {
            // set方法不为空
            // pvs属性集合不为空且不包含必须检查的属性
            if (pd.getWriteMethod() != null && (pvs == null || !pvs.contains(pd.getName()))) {
                // 判断是否是简单属性,如基础数据类型或者string
                boolean isSimple = BeanUtils.isSimpleProperty(pd.getPropertyType());
                // 判断是否不满足设定的检查标准
                boolean unsatisfied = (dependencyCheck == AbstractBeanDefinition.DEPENDENCY_CHECK_ALL) ||
                        (isSimple && dependencyCheck == AbstractBeanDefinition.DEPENDENCY_CHECK_SIMPLE) ||
                        (!isSimple && dependencyCheck == AbstractBeanDefinition.DEPENDENCY_CHECK_OBJECTS);
                // 不满足,抛出异常
                if (unsatisfied) {
                    throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, pd.getName(),
                            "Set this property value or disable dependency checking for this bean.");
                }
            }
        }
    }

这一块的逻辑就简单多了,功能就是为了验证要求进行依赖检查的属性pds拥有对应的set方法,具体看代码注释就可以了。

6. AbstractAutowireCapableBeanFactory#applyPropertyValues

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

        MutablePropertyValues mpvs = null;
        List<PropertyValue> original;

        if (pvs instanceof MutablePropertyValues) {
            mpvs = (MutablePropertyValues) pvs;
            if (mpvs.isConverted()) {
                // Shortcut: use the pre-converted values as-is.
                try {
                    // 如果属性已经转化完成,直接设置,通过反射调用set方法设置
                    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;
        }
        // 获取解析器
        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集合
                deepCopy.add(pv);
            }
            else {
                String propertyName = pv.getName();
                Object originalValue = pv.getValue();
                // 如果是Autowire注入
                if (originalValue == AutowiredPropertyMarker.INSTANCE) {
                    // 获取set方法
                    Method writeMethod = bw.getPropertyDescriptor(propertyName).getWriteMethod();
                    if (writeMethod == null) {
                        throw new IllegalArgumentException("Autowire marker for property without write method: " + pv);
                    }
                    // 原始值构造为持有set方法的DependencyDescriptor
                    originalValue = new DependencyDescriptor(new MethodParameter(writeMethod, 0), true);
                }
                // 使用解析器解析原始值,例如将引用转换为IoC容器中实例化对象引用!
                Object resolvedValue = valueResolver.resolveValueIfNecessary(pv, originalValue);
                Object convertedValue = resolvedValue;
                // 判断是否可转化,需要满足条件:
                // 1、可写属性
                // 2、非内嵌属性或者索引属性(nested or indexed property)
                boolean convertible = bw.isWritableProperty(propertyName) &&
                        !PropertyAccessorUtils.isNestedOrIndexedProperty(propertyName);
                if (convertible) {
                    // 如果可以转化,进行值转化
                    // 转化可能是string到int之间的兼容转化
                    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 {
            // 设置值,通过反射调用set方法设置
            bw.setPropertyValues(new MutablePropertyValues(deepCopy));
        }
        catch (BeansException ex) {
            throw new BeanCreationException(
                    mbd.getResourceDescription(), beanName, "Error setting property values", ex);
        }
    }

应用属性值到bean中,说白了,就是调用set方法,设置值,大部分代码在于为属性值做解析和转化等功能,而真正做这件事到其实就setPropertyValues方法:

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

跟踪调用链,在底层调用方法为BeanWrapperImpl#setValue

        @Override
        public void setValue(final @Nullable Object value) throws Exception {
            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);
                writeMethod.invoke(getWrappedInstance(), value);
            }
        }

可以看到,原理是使用了反射,执行debug,可以看到writeMethod就是set方法:

setValue

总结

阅读populateBean源码之前,还以为会相对简单,以为就是获取set方法,再通过set方法进行赋值,结果实际情况远远复杂于原先到设想,只能说,spring真是一个庞大到工程。总而言之,populateBean核心思想便是对属性值进行填充,属性值可能是基本数据类型之类对,也可能是需要引用其他bean的复杂类型,整体源码围绕这一思想展开。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 151,688评论 1 330
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 64,559评论 1 273
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 101,749评论 0 226
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 42,581评论 0 191
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 50,741评论 3 271
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 39,684评论 1 192
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,122评论 2 292
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 29,847评论 0 182
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 33,441评论 0 228
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 29,939评论 2 232
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,333评论 1 242
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 27,783评论 2 236
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,275评论 3 220
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,830评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,444评论 0 180
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 34,553评论 2 249
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 34,618评论 2 249