关于spring:五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<String> 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<T> 的原始类型,嵌套档次加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<String> 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<String, Object> 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<String, Object> 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<String, Object> findAutowireCandidates(
            @Nullable String beanName, Class<?> requiredType, DependencyDescriptor descriptor) {
        // 查找 Spring 中给定类型的 bean 名称
        String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                this, requiredType, true, descriptor.isEager());
        Map<String, Object> result = new LinkedHashMap<>(candidateNames.length);
        // 先解析 Spring 中游离的对象,如果类型和所需类型匹配则退出到后果中
        for (Map.Entry<Class<?>, 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<String, Object> 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<String, Object> 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。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理