spring源码解析:spring是如何进行依赖注入的


简介

spring在启动过程中会创建一部分单例的bean,在bean完成实例化后或者用有参构造进行实例化时,会进行属性注入,这是会根据程序的配置构造依赖。

依赖注入的几种方式

spring在进行依赖注入时,主要分为构造函数注入和setter方法(@Autowired放在属性或者setter方法上的)两种,spring在对一个bean初始化时就会开始查找需要的依赖,并提前加载创建需要的依赖完成注入。其次还有一种使用@DependsOn注解,可以在bean加载之前提前创建该注解的依赖。

构造函数注入

在spring创建bean时,首先会找到bean的构造函数,然后通过指定构造函数创建bena的实例,创建完成实例后,再对相关的属性注入。在以上步骤中,如果找到的是有参构造函数,那么spring会先参构造的注入,先创建需要的参数进行注入。代码如下:

1.首先会调用getbean方法创建bean。后面找需要参数也使用getBean方法创建参数。总之spring在创建bean时总是会调用getBean,只不过调用的位置和时机不同。

public void preInstantiateSingletons() throws BeansException {
    ...
    for (String beanName : beanNames) {
    ...
    getBean(beanName);
    ...
    }
}

2.间会经过各种验证,推断构造方法,最后会调用autowireConstructor方法。间方法调用链条:gtBean—>doGetBean—>createBean—->doCreateBean—>createBeanInstance—>autowireConstructor

    protected BeanWrapper autowireConstructor(
            String beanName, RootBeanDefinition mbd, @Nullable Constructor<?>[] ctors, @Nullable Object[] explicitArgs) {

        return new ConstructorResolver(this).autowireConstructor(beanName, mbd, ctors, explicitArgs);
    }

public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd,
            @Nullable Constructor<?>[] chosenCtors, @Nullable Object[] explicitArgs) {
        //bean实例化的包装器
        BeanWrapperImpl bw = new BeanWrapperImpl();
        this.beanFactory.initBeanWrapper(bw);

        //存放要使用的构造函数
        Constructor<?> constructorToUse = null;
        ArgumentsHolder argsHolderToUse = null;
        //存放要使用的构造函数的参数
        Object[] argsToUse = null;

        //如果已经指定了构造函数的参数,那么直接使用
        if (explicitArgs != null) {
            argsToUse = explicitArgs;
        }
        //尝试从缓存中获取构造函数和参数
        else {
            Object[] argsToResolve = null;
            synchronized (mbd.constructorArgumentLock) {
                constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
                if (constructorToUse != null && mbd.constructorArgumentsResolved) {
                    // Found a cached constructor...
                    argsToUse = mbd.resolvedConstructorArguments;
                    if (argsToUse == null) {
                        argsToResolve = mbd.preparedConstructorArguments;
                    }
                }
            }
            //如果缓存的参数不为空,就开始解析参数
            if (argsToResolve != null) {
                argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve);
            }
        }
        //如果构造函数或参数不存在,那么说明继续推断
        if (constructorToUse == null || argsToUse == null) {
            // Take specified constructors, if any.
            Constructor<?>[] candidates = chosenCtors;
            //如果没有候选的构造函数,那么直接找默认的无参构造
            if (candidates == null) {
                Class<?> beanClass = mbd.getBeanClass();
                try {
                    //是否允许非public的构造方法访问,然后根据反射获取公开或者非公开的构造
                    candidates = (mbd.isNonPublicAccessAllowed() ?
                            beanClass.getDeclaredConstructors() : beanClass.getConstructors());
                }
                catch (Throwable ex) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                            "Resolution of declared constructors on bean Class [" + beanClass.getName() +
                            "] from ClassLoader [" + beanClass.getClassLoader() + "] failed", ex);
                }
            }

            //如果只有一个候选构造,且没有参数,那么说明是默认的无参构造
            if (candidates.length == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
                Constructor<?> uniqueCandidate = candidates[0];
                if (uniqueCandidate.getParameterCount() == 0) {
                    //加锁设置缓存,有可能会再次解析或多线程解析。直接从缓存中取
                    synchronized (mbd.constructorArgumentLock) {
                        mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
                        mbd.constructorArgumentsResolved = true;
                        mbd.resolvedConstructorArguments = EMPTY_ARGS;
                    }
                    //实例化bean
                    bw.setBeanInstance(instantiate(beanName, mbd, uniqueCandidate, EMPTY_ARGS));
                    return bw;
                }
            }

            /*
            * 没有默认的无参构造,那么需要继续推断构造函数
            *
            * autowiring为true表示自动注入,有@Autowried注解的构造,或者注入模型为AUTOWIRE_CONSTRUCTOR的就是自动注入
            *
            * minNrOfArgs记录需要的最少的参数值。有可能有多个候选构造,如果构造函数的参数小于这个值,那么肯定就不会是这个构造函数,直接跳过
            * 如果开发者指定了参数,那么就是参数的个数就是该值,没有指定则为0
            * */
            boolean autowiring = (chosenCtors != null ||
                    mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
            ConstructorArgumentValues resolvedValues = null;

            int minNrOfArgs;
            if (explicitArgs != null) {
                minNrOfArgs = explicitArgs.length;
            }
            else {
                ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
                resolvedValues = new ConstructorArgumentValues();
                minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
            }
            // 对候选构造方法进行排序,public的方法排在最前面,都是public的情况下参数个数越多越靠前
            AutowireUtils.sortConstructors(candidates);
            /*
            * 记录构造函数与参数的最小差异值:
            *     spring会排序遍历所有的构造函数,并且会去找构造函数上的参数,在寻找的过程中会记录每一个构造函数与参数的匹配程度,越匹配的这个差异值就越小
            * */
            int minTypeDiffWeight = Integer.MAX_VALUE;
            /*
            * 表示有歧义的构造函数,有可能多个构造函数的差异值一样,就不知道用那个构造函数了,就会放入该队列。再根据是否宽松或严格模式去判断,宽松则取第一个,严格则抛出异常
            * */
            Set<Constructor<?>> ambiguousConstructors = null;
            //记录遍历时,程序抛出的异常
            Deque<UnsatisfiedDependencyException> causes = null;

            for (Constructor<?> candidate : candidates) {
                int parameterCount = candidate.getParameterCount();

                //经过多次遍历可能已经找到了需要的构造函数和参数,并且再比较找到的参数数量是否大于本次的,是的话那么后面的不需要再找了
                // ,因为是排过序的,后面的参数数量只会小于本次的
                if (constructorToUse != null && argsToUse != null && argsToUse.length > parameterCount) {
                    // Already found greedy constructor that can be satisfied ->
                    // do not look any further, there are only less greedy constructors left.
                    break;
                }
                //如果这个构造函数的参数小于最少需要的构造参数个数值,那么直接略过
                if (parameterCount < minNrOfArgs) {
                    continue;
                }

                ArgumentsHolder argsHolder;
                Class<?>[] paramTypes = candidate.getParameterTypes();
                /*
                * 如果进入到了这里,说明开发者没有指定构造参数。
                *
                * 那么spring会根据每一个参数类型和名称到容器中取匹配合适的值
                * */
                if (resolvedValues != null) {
                    try {
                        String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, parameterCount);
                        if (paramNames == null) {
                            ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
                            if (pnd != null) {
                                paramNames = pnd.getParameterNames(candidate);
                            }
                        }
                        //根据当前的构造函数,查找符合条件的参数
                        argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames,
                                getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1);
                    }
                    catch (UnsatisfiedDependencyException ex) {
                        if (logger.isTraceEnabled()) {
                            logger.trace("Ignoring constructor [" + candidate + "] of bean '" + beanName + "': " + ex);
                        }
                        // Swallow and try next constructor.
                        if (causes == null) {
                            causes = new ArrayDeque<>(1);
                        }
                        causes.add(ex);
                        continue;
                    }
                }
                /*
                * 如果指定了构造函数的参数,那么一直找到符合指定参数个数的构造函数,并创建一个参数持有器
                * */
                else {
                    // Explicit arguments given -> arguments length must match exactly.
                    if (parameterCount != explicitArgs.length) {
                        continue;
                    }
                    argsHolder = new ArgumentsHolder(explicitArgs);
                }

                /*
                * 下面这段代码是计算构造函数与参数的差异化的值:
                *     根据不同的模式(宽松/严格)计算最小差异值
                * */
                int typeDiffWeight = (mbd.isLenientConstructorResolution() ?
                        argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
                // Choose this constructor if it represents the closest match.
                //此次计算的差异值比之前的更小,那么就取当前这个,然后重新赋值给minTypeDiffWeight,以便后续遍历使用
                if (typeDiffWeight < minTypeDiffWeight) {
                    constructorToUse = candidate;
                    argsHolderToUse = argsHolder;
                    argsToUse = argsHolder.arguments;
                    minTypeDiffWeight = typeDiffWeight;
                    ambiguousConstructors = null;//这里复制为null,因为找到合适的了,之前即使有歧义的构造函数已经无所谓了
                }
                //计算出来差异值一样的多个函数表示存在歧义,加入到歧义队列。constructorToUse != null表示至少已经存在一个构造函数,因为两个及以上才会存在歧义
                else if (constructorToUse != null && typeDiffWeight == minTypeDiffWeight) {
                    if (ambiguousConstructors == null) {
                        ambiguousConstructors = new LinkedHashSet<>();
                        ambiguousConstructors.add(constructorToUse);
                    }
                    ambiguousConstructors.add(candidate);
                }
            }
            //如果没有推断出构造函数,则抛出异常
            if (constructorToUse == null) {
                if (causes != null) {
                    UnsatisfiedDependencyException ex = causes.removeLast();
                    for (Exception cause : causes) {
                        this.beanFactory.onSuppressedException(cause);
                    }
                    throw ex;
                }
                throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "Could not resolve matching constructor on bean class [" + mbd.getBeanClassName() + "] " +
                        "(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities)");
            }
            //严格模式下,不允许存在有歧义的构造函数
            else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName,
                        "Ambiguous constructor matches found on bean class [" + mbd.getBeanClassName() + "] " +
                        "(hint: specify index/type/name arguments for simple parameters to avoid type ambiguities): " +
                        ambiguousConstructors);
            }
            //如果开发者没有指定参数,且spring找到了参数,那么将参数缓存。(不会缓存开发者指定的参数,因为不知道何时开发者就会换掉指定的参数)
            if (explicitArgs == null && argsHolderToUse != null) {
                argsHolderToUse.storeCache(mbd, constructorToUse);
            }
        }
        //实例化.走到这里说明已经找到了构造方法
        Assert.state(argsToUse != null, "Unresolved constructor arguments");
        bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
        return bw;
    }

autowireConstructor这个方法的大概意思是:根据传入的构造函数集合和显示指定的参数,查找符合条件的构造函数和参数,并创建一个bean的实例。

一般来说显示参数为null,这里会将我们的构造函数集合排序,然后找到推断出来的构造方法,再去找构造函数上的参数

3.createArgumentArray方法创建参数。这个方法的大概意思就是遍历所有的参数集合,一个一个参数的查找,先找bean定义中,没有则在spring容器中找,最后会调用beanFactory.resolveDependency通用处理依赖的方法,一般来说会调用getBean方法创建需要的参数

private ArgumentsHolder createArgumentArray(
            String beanName, RootBeanDefinition mbd, @Nullable ConstructorArgumentValues resolvedValues,
            BeanWrapper bw, Class<?>[] paramTypes, @Nullable String[] paramNames, Executable executable,
            boolean autowiring, boolean fallback) throws UnsatisfiedDependencyException {

        //获取类型转换器。如果开发者没有自定义类型转化器,那么就用默认的类型转换器
        TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
        TypeConverter converter = (customConverter != null ? customConverter : bw);

        //参数持有器,记录
        ArgumentsHolder args = new ArgumentsHolder(paramTypes.length);
        //参数值的封装
        Set<ConstructorArgumentValues.ValueHolder> usedValueHolders = new HashSet<>(paramTypes.length);
        Set<String> autowiredBeanNames = new LinkedHashSet<>(4);

        //开始遍历所有的参数
        for (int paramIndex = 0; paramIndex < paramTypes.length; paramIndex++) {
            Class<?> paramType = paramTypes[paramIndex];
            String paramName = (paramNames != null ? paramNames[paramIndex] : "");
            // Try to find matching constructor argument value, either indexed or generic.
            ConstructorArgumentValues.ValueHolder valueHolder = null;

            //这个分支表示如果bean定义中设置了参数,就从bean定义中获取
            if (resolvedValues != null) {
                //先通过索引+类型+名称匹配是否已经存在了参数
                valueHolder = resolvedValues.getArgumentValue(paramIndex, paramType, paramName, usedValueHolders);
                // If we couldn't find a direct match and are not supposed to autowire,
                // let's try the next generic, untyped argument value as fallback:
                // it could match after type conversion (for example, String -> int).
                //如果没有找到匹配的参数,且不是自动注入的,尝试解析需要类型转换的
                if (valueHolder == null && (!autowiring || paramTypes.length == resolvedValues.getArgumentCount())) {
                    valueHolder = resolvedValues.getGenericArgumentValue(null, null, usedValueHolders);
                }
            }
            if (valueHolder != null) {
                // We found a potential match - let's give it a try.
                // Do not consider the same value definition multiple times!
                usedValueHolders.add(valueHolder);
                Object originalValue = valueHolder.getValue();
                Object convertedValue;
                if (valueHolder.isConverted()) {
                    convertedValue = valueHolder.getConvertedValue();
                    args.preparedArguments[paramIndex] = convertedValue;
                }
                else {
                    MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex);
                    try {
                        convertedValue = converter.convertIfNecessary(originalValue, paramType, methodParam);
                    }
                    catch (TypeMismatchException ex) {
                        throw new UnsatisfiedDependencyException(
                                mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam),
                                "Could not convert argument value of type [" +
                                        ObjectUtils.nullSafeClassName(valueHolder.getValue()) +
                                        "] to required type [" + paramType.getName() + "]: " + ex.getMessage());
                    }
                    Object sourceHolder = valueHolder.getSource();
                    if (sourceHolder instanceof ConstructorArgumentValues.ValueHolder) {
                        Object sourceValue = ((ConstructorArgumentValues.ValueHolder) sourceHolder).getValue();
                        args.resolveNecessary = true;
                        args.preparedArguments[paramIndex] = sourceValue;
                    }
                }
                args.arguments[paramIndex] = convertedValue;
                args.rawArguments[paramIndex] = originalValue;
            }
            //到这表示还没有找到匹配的值,需要自动装配。既然通过构造函数注入,那么肯定是需要明确参数值的,如果找不到,那么就抛出异常。
            else {
                MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex);
                // No explicit match found: we're either supposed to autowire or
                // have to fail creating an argument array for the given constructor.
                if (!autowiring) { //上面没有找到值,那么只能自动注入,如果不允许自动注入,那么抛出异常
                    throw new UnsatisfiedDependencyException(
                            mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam),
                            "Ambiguous argument values for parameter of type [" + paramType.getName() +
                                    "] - did you specify the correct bean references as arguments?");
                }
                try {
                    //在spring容器中查找对应的类型
                    Object autowiredArgument = resolveAutowiredArgument(
                            methodParam, beanName, autowiredBeanNames, converter, fallback);
                    args.rawArguments[paramIndex] = autowiredArgument;
                    args.arguments[paramIndex] = autowiredArgument;
                    args.preparedArguments[paramIndex] = autowiredArgumentMarker;
                    args.resolveNecessary = true;
                }
                catch (BeansException ex) {
                    throw new UnsatisfiedDependencyException(
                            mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam), ex);
                }
            }
        }

        for (String autowiredBeanName : autowiredBeanNames) {
            this.beanFactory.registerDependentBean(autowiredBeanName, beanName);
            if (logger.isDebugEnabled()) {
                logger.debug("Autowiring by type from bean name '" + beanName +
                        "' via " + (executable instanceof Constructor ? "constructor" : "factory method") +
                        " to bean named '" + autowiredBeanName + "'");
            }
        }

        return args;
    }

在上述代码中,循环查找每一个参数,最后将参数集合返回,最后在autowireConstructor中拿着构造函数和所需要的参数反射调用,完成bean的实例化。

setter方法注入

紧跟着上一步,bean的实例化之后,spring就会开始对bean的属性进行注入。实例化时可能会注入一部分字段,也有可能部分字段使用了@Autowried注入的,或者@Reource,那么在此时就在这里进行注入。

1.整个过程还是发生在spring的启动过程中的bean的生命周期里。调用链如下:
gtBean—>doGetBean—>createBean—->doCreateBean—>createBeanInstance之后的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.

        /*
        * 这里自己可以自己实现InstantiationAwareBeanPostProcessors接口,用于修改bean的属性填充,如果返回false表示不需要spring后续填充
        *
        * */
        if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
            for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
                if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
                    return;
                }
            }
        }

        /*
        * 就要开始注入属性了。根据注入模型注入bean的属性。
        *     AUTOWIRE_BY_NAME 通过名称注入
        *     AUTOWIRE_BY_TYPE 通过类型注入
        *     AUTOWIRE_CONSTRUCTOR 通过构造函数注入
        *
        *     一般为0 即AUTOWIRE_NO 表示没有注入模式
        *
        * */
        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;
        }

        /*
        * 这里表示开始属性注入。根据属性的上的注解,分别使用不同的后置处理器来处理
        *
        *     是否存在实现了InstantiationAwareBeanPostProcessor的处理器。初始化时这里为true,应为有两个是spring自带的内置处理器实现了该接口
        *         CommonAnnotationBeanPostProcessor后置处理器解析,处理@Resource
        *         AutowiredAnnotationBeanPostProceoor后置处理器解析,处理@Autowired
        *
        * 用了@Autowire注解的属性注入就是在这里进行的(AutowiredAnnotationBeanPostProcessor处理器)
        *
        * */
        boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
        boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);

        PropertyDescriptor[] filteredPds = null;
        if (hasInstAwareBpps) {
            if (pvs == null) {//这里再次调用getPropertyValues()是为了给个默认值
                pvs = mbd.getPropertyValues();
            }
            for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
                PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
                if (pvsToUse == null) {
                    if (filteredPds == null) {
                        filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
                    }
                    pvsToUse = bp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
                    if (pvsToUse == null) {
                        return;
                    }
                }
                pvs = pvsToUse;
            }
        }
        if (needsDepCheck) {
            if (filteredPds == null) {
                filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
            }
            checkDependencies(beanName, mbd, filteredPds, pvs);
        }

        if (pvs != null) {
            applyPropertyValues(beanName, mbd, bw, pvs);
        }
    }

在上述代码里可以看到,不同的注解注入的属性由不同的处理器负责,那么看看@Autowried注解的。

2.@Autowried注解是由AutowiredAnnotationBeanPostProcessor处理器来处理依赖的,在这个类中有两个内部类AutowiredMethodElement,AutowiredFieldElement分别对应的setter方法上和字段上使用 @Autowried注入的,由这两个内部类来处理。

方法调用链:populateBean—>postProcessProperties—>metadata.inject

public void inject(Object target, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
        Collection<InjectedElement> checkedElements = this.checkedElements;
        Collection<InjectedElement> elementsToIterate =
                (checkedElements != null ? checkedElements : this.injectedElements);
        if (!elementsToIterate.isEmpty()) {
            for (InjectedElement element : elementsToIterate) {
                element.inject(target, beanName, pvs);
            }
        }
    }

上述方法是把所有的需要注入的属性(不管是方法还是字段),都封装为一个InjectedElement,然后拿到集合开始一个一个调用各自的inject方法(不同的实现类的逻辑不同),方法和字段的调用链为:

  1. inject—>resolveFieldValue—>resolveFieldValue—>beanFactory.resolveDependency
  2. inject—>resolveFieldValue—>resolveMethodArguments—>beanFactory.resolveDependency

可以看到不管是字段的还是setter方法的最后也都是调用beanFactory.resolveDependency方法来处理依赖,同上面构造方法注入一致。那么下面来看看beanFactory.resolveDependency方法的具体实现。

resolveDependency方法解析

resolveDependency方法是Spring进行依赖查找的核心 ,用于解析和获取 bean 之间的依赖关系。通常用于处理注入、自动装配、依赖查找等操作。

// Spring 进行依赖查找的核心 ,处理bean所需的依赖,包括属性注入的字段
    /**
     * @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());

        // 检查依赖类型是否为 Optional,如果是,创建 Optional 依赖
        if (Optional.class == descriptor.getDependencyType()) {
            return createOptionalDependency(descriptor, requestingBeanName);
        }
        // 检查依赖类型是否为 ObjectFactory 或 ObjectProvider,如果是,创建 DependencyObjectProvider
        else if (ObjectFactory.class == descriptor.getDependencyType() ||
                ObjectProvider.class == descriptor.getDependencyType()) {
            return new DependencyObjectProvider(descriptor, requestingBeanName);
        }
        // 检查依赖类型是否为 javaxInjectProviderClass(JSR-330 Provider 类型),如果是,使用 Jsr330Factory 创建依赖 Provider
        else if (javaxInjectProviderClass == descriptor.getDependencyType()) {
            return new Jsr330Factory().createDependencyProvider(descriptor, requestingBeanName);
        }
        else {
            // 使用 AutowireCandidateResolver 获取懒加载代理(如果有的话)
            Object result = getAutowireCandidateResolver().getLazyResolutionProxyIfNecessary(
                    descriptor, requestingBeanName);

            // 如果没有懒加载代理,尝试解析依赖
            if (result == null) {
                result = doResolveDependency(descriptor, requestingBeanName, autowiredBeanNames, typeConverter);
            }

            return result;
        }
    }

通常情况下,在这里最后会调用doResolveDependency方法解析依赖,这里也是解析依赖的最核心方法

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

        InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
        try {
            /*1.尝试快速查找 AutowiredAnnotationBeanPostProcessor.ShortcutDependencyDescriptor实现*/
            Object shortcut = descriptor.resolveShortcut(this);
            if (shortcut != null) {
                return shortcut;
            }
            //2. 注入指定值,QualifierAnnotationAutowireCandidateResolver解析@Value会用到
            Class<?> type = descriptor.getDependencyType();
            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);
                    //el表达式解析
                    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()));
                }
            }
            //3.处理构造参为Collection,map,数组等这样类型的
            Object multipleBeans = resolveMultipleBeans(descriptor, beanName, autowiredBeanNames, typeConverter);
            if (multipleBeans != null) {
                return multipleBeans;
            }

            //4.正常的注入查找:这里有可能是bean定义,一个实例对象
            Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);
            //如果还是没有找到,又必须需要这个依赖,那么抛出异常
            if (matchingBeans.isEmpty()) {
                if (isRequired(descriptor)) {
                    raiseNoMatchingBeanFound(type, descriptor.getResolvableType(), descriptor);
                }
                return null;
            }

            //记录注入的bean名称,和bean对象实例
            String autowiredBeanName;
            Object instanceCandidate;

            //如果找到多个匹配的,
            if (matchingBeans.size() > 1) {
                //那么根据 @Primary -> @Priority -> 方法名称或字段名称  权重匹配最合适的
                autowiredBeanName = determineAutowireCandidate(matchingBeans, descriptor);
                //如果找不到,也不是集合或数组的,那么抛出异常
                if (autowiredBeanName == null) {
                    if (isRequired(descriptor) || !indicatesMultipleBeans(type)) {
                        return descriptor.resolveNotUnique(descriptor.getResolvableType(), matchingBeans);
                    }
                    //找不到,集合类型的返回null
                    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);
            }

            /*
            * 调用getBean从容器中获取bean
            *
            *     这里如果bean没有实例化会在提前这里实例化
            *     可能会存在循环依赖
            * */
            if (instanceCandidate instanceof Class) {
                instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
            }
            //如果获取bean的实例失败,且是必须依赖的,在这抛出异常
            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);
        }
    }

上述方法主要作用是根据 DependencyDescriptor 中的信息,解析和获取依赖的 Bean 实例。在解析过程中,它处理了各种情况,包括是否有快捷方式、是否有建议的值、是否有多个候选 Bean、是否需要类型转换、是否需要解析注解、是否满足必需条件等等

总结

综上所述,不管是哪种依赖的注入 ,最后都会调用resolveDependency来处理依赖,只是在不同的位置调用该方法的时机不同


文章作者: Needle
转载声明:本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Needle !
  目录
  评论