五、Spring依赖解析实现

Spring对BeanFactory底层的最终实现是DefaultListableBeanFactory,DefaultListableBeanFactory对resolveDependency方法实现的源码如下。

    /**
     * @param descriptor         字段或方法的依赖描述信息
     * @param requestingBeanName 需要注入依赖的 bean 的名称
     * @param autowiredBeanNames 需要注入的依赖的 bean 名称的集合,解析的结果会存放该集合中
     * @param typeConverter      类型转换
     * @return
     * @throws BeansException
     */
    @Override
    @Nullable
    public Object resolveDependency(DependencyDescriptor descriptor, @Nullable String requestingBeanName,
            @Nullable Set autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {

        descriptor.initParameterNameDiscovery(getParameterNameDiscoverer());
        if (Optional.class == descriptor.getDependencyType()) {
            // 解析 Optional 依赖
            return createOptionalDependency(descriptor, requestingBeanName);
        } else if (ObjectFactory.class == descriptor.getDependencyType() ||
                ObjectProvider.class == descriptor.getDependencyType()) {
            // 解析 ObjectFactory 或 ObjectProvider 依赖
            return new DependencyObjectProvider(descriptor, requestingBeanName);
        } else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
            // 解析 javax.inject.Provider 注解标注的依赖
            return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
        } else {
            // 懒加载的对象返回代理对象
            Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
                    descriptor, requestingBeanName);
            if (result == null) {
                // 其他对象进行解析
                result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
            }
            return result;
        }
    }

解析依赖的方法,根据不同的依赖类型使用不同的解析方式。对于Optional、ObjectFactory、ObjectProvider依赖类型,由于需要解析的是其泛型的实际类型,因此Spring会将依赖描述信息重新包装为另一个DependencyDescriptor ,然后再解析。而Java规范JSR-330中注解javax.inject.Provider的处理则只是将实现委托给另一个类处理。对于不同类型的依赖解析,最终都会调用doResolveDependency方法。以Optional类型的解析方法createOptionalDependency为例源码如下

    private Optional createOptionalDependency(
            DependencyDescriptor descriptor, @Nullable String beanName, final Object... args) {

        // 包装依赖描述信息,解析依赖的类型时会将嵌套层次加1
        // 例如原来要解析的类型是 Optional 的原始类型,嵌套层次加1后会解析泛型类型的实际类型 T
        DependencyDescriptor descriptorToUse = new NestedDependencyDescriptor(descriptor) {
            @Override
            public boolean isRequired() {
                return false;
            }

            @Override
            public Object resolveCandidate(String beanName, Class requiredType, BeanFactory beanFactory) {
                return (!ObjectUtils.isEmpty(args) ? beanFactory.getBean(beanName, args) :
                        super.resolveCandidate(beanName, requiredType, beanFactory));
            }
        };
        // 然后真正解析依赖
        Object result = doResolveDependency(descriptorToUse, beanName, null, null);
        // 再将解析出的依赖包装到 Optional 中
        return (result instanceof Optional ? (Optional) result : Optional.ofNullable(result));
    }

进入doResolveDependency方法

    public Object doResolveDependency(DependencyDescriptor descriptor, @Nullable String beanName,
            @Nullable Set autowiredBeanNames, @Nullable TypeConverter typeConverter) throws BeansException {
        ... 省略部分代码
            // 快捷解析依赖
            Object shortcut = descriptor.resolveShortcut(this);
            if (shortcut != null) {
                return shortcut;
            }

            Class type = descriptor.getDependencyType();
            // 先根据 @Value 注解解析依赖对象
            Object value = getAutowireCandidateResolver().getSuggestedValue(descriptor);
            if (value != null) {
                if (value instanceof String) {
                    // 然后对占位符处理以及表达式进行处理
                    String strVal = resolveEmbeddedValue((String) value);
                    BeanDefinition bd = (beanName != null && containsBean(beanName) ?
                            getMergedBeanDefinition(beanName) : null);
                    value = evaluateBeanDefinitionString(strVal, bd);
                }
                TypeConverter converter = (typeConverter != null ? typeConverter : getTypeConverter());
                try {
                    // 将结果进行类型转换
                    return converter.convertIfNecessary(value, type, descriptor.getTypeDescriptor());
                } catch (UnsupportedOperationException ex) {
                    ... 省略部分代码
                }
            }

            // 尝试解析包含多个 bean 的依赖对象
            Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
            if (multipleBeans != null) {
                return multipleBeans;
            }

            // 查找所需类型的依赖
            Map matchingBeans = findAutowireCandidates(beanName, type, descriptor);
            if (matchingBeans.isEmpty()) {
                if (isRequired(descriptor)) {
                    // 依赖不存在,抛出异常
                    raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
                }
                return null;
            }

            String autowiredBeanName;
            Object instanceCandidate;

            if (matchingBeans.size() > 1) {
                // 存在多个类型相同的依赖,确定使用哪个依赖
                autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
                if (autowiredBeanName == null) {
                    if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
                        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.
                Map.Entry entry = matchingBeans.entrySet().iterator().next();
                autowiredBeanName = entry.getKey();
                instanceCandidate = entry.getValue();
            }

            if (autowiredBeanNames != null) {
                autowiredBeanNames.add(autowiredBeanName);
            }
            if (instanceCandidate instanceof Class) {
                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;
    }

对于集合类型以及单一类型,最终都会调用findAutowireCandidates方法查找自动装配的候选对象,对于集合类型会把查找到的候选对象包装为对应所需的类型,对于单一类型则需要确认最终使用哪个依赖。进入findAutowireCandidates方法

    protected Map findAutowireCandidates(
            @Nullable String beanName, Class requiredType, DependencyDescriptor descriptor) {
        // 查找 Spring 中给定类型的 bean 名称
        String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                this, requiredType, true, descriptor.isEager());
        Map result = new LinkedHashMap<>(candidateNames.length);
        // 先解析 Spring 中游离的对象,如果类型和所需类型匹配则加入到结果中
        for (Map.Entry, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {
            Class autowiringType = classObjectEntry.getKey();
            if (autowiringType.isAssignableFrom(requiredType)) {
                Object autowiringValue = classObjectEntry.getValue();
                autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
                if (requiredType.isInstance(autowiringValue)) {
                    result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
                    break;
                }
            }
        }
        // 然后解析 Spring 中注册 BeanDefinition 中的名称
        for (String candidate : candidateNames) {
            if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
                // 依赖非 bean 自身,并且 bean 可以作为候选项,加入到结果中
                addCandidateEntry(result, candidate, descriptor, requiredType);
            }
        }
        ... 省略回退处理代码,和上述候选名称循环类似
        return result;
    }

候选对象的获取主要有两个来源,一个是游离对象,一个是Spring中的bean,Spring 根据类型获取到对应的实例后添加到返回结果。这也印证了前面文章所说的依赖注入的依赖来源。需要留意的是对isAutowireCandidate方法的调用,isAutowireCandidate方法用于判断一个一个对象是否可以作为候选项,其内部出了判断bean定义中是否可以作为候选项的标识,还会判断泛型、@Qualifier 等。对于单一类型的依赖解析,如果查找到了多个bean,则需要判断到底使用哪一个bean作为结果,进入determineAutowireCandidate方法

    protected String determineAutowireCandidate(Map candidates, DependencyDescriptor descriptor) {
        Class requiredType = descriptor.getDependencyType();
        // 先根据 primary 判断
        String primaryCandidate = determinePrimaryCandidate(candidates, requiredType);
        if (primaryCandidate != null) {
            return primaryCandidate;
        }
        // primary 不存在,则根据优先级判断
        String priorityCandidate = determineHighestPriorityCandidate(candidates, requiredType);
        if (priorityCandidate != null) {
            return priorityCandidate;
        }
        // Fallback
        for (Map.Entry entry : candidates.entrySet()) {
            String candidateName = entry.getKey();
            Object beanInstance = entry.getValue();
            // 依赖为游离对象或指定依赖的 bean 名称匹配,直接返回
            if ((beanInstance != null && this.resolvableDependencies.containsValue(beanInstance)) ||
                    matchesBeanName(candidateName, descriptor.getDependencyName())) {
                return candidateName;
            }
        }
        return null;
    }

这里优先选择标记 primary 为 true 的 bean,如果都没有标注则会选择一个优先级最高的 bean,如果存在多个优先级相同的 bean 会抛出异常。最后会将游离对象或和依赖的名称匹配的 bean 作为结果进行返回。

总结

Spring 依赖解析会优先根据 @Value 注解进行解析,并且支持多种类型。对于类型为 Optional、ObjectFactory 的依赖 Spring 会将依赖包装后返回,其他类型又分为集合类型和单一类型,对于集合类型 Spring 查找对所有依赖后直接包装为对应的类型返回即可,对于单一类型 Spring 会优先考虑 primary、最高优先级、和所需 bean 名称匹配的 bean。

你可能感兴趣的:(javaspring)