ConstructorResolver构造方法实例化解析以及注入

博客围绕Java开发语言展开,但具体内容缺失。Java是重要的后端开发语言,应用广泛。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

class ConstructorResolver {

    // 实例化普通类
    private Object instantiate(String beanName, RootBeanDefinition mbd, Constructor<?> constructorToUse, Object[] argsToUse) {
        // 	private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();
        // 默认的实例化策略是CglibSubclassingInstantiationStrategy
        return this.beanFactory.getInstantiationStrategy().instantiate(mbd, beanName, this.beanFactory, constructorToUse, argsToUse)
        {
            // 如果没有方法覆盖的情况,只有@Looup,或者xml中配置了方法覆盖的情况下,才不为空
            if (!bd.hasMethodOverrides()) {
                // 通过构造方法反射创建对象
                return BeanUtils.instantiateClass(ctor, args);
            } else {
                // 使用
                return instantiateWithMethodInjection(bd, beanName, owner, ctor, args) {
                    // 新建Cglib子类生成器
                    CglibSubclassCreator creator = new CglibSubclassCreator(bd, owner);
                    // 实例化子类对象
                    return creator.instantiate(ctor, args) {
                        // 创建CGLIB子类的Class对象
                        Class<?> subclass = createEnhancedSubclass(this.beanDefinition) {
                            Enhancer enhancer = new Enhancer();
                            enhancer.setSuperclass(beanDefinition.getBeanClass());
                            enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
                            if (this.owner instanceof ConfigurableBeanFactory) {
                                ClassLoader cl = ((ConfigurableBeanFactory) this.owner).getBeanClassLoader();
                                enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(cl));
                            }
                            // 设置过滤器,在内部可以按照条件指定执行某一个Callback
                            // 因为Callback可以给定多个
                            enhancer.setCallbackFilter(new MethodOverrideCallbackFilter(beanDefinition));
                            // 限制回调的类型
                            enhancer.setCallbackTypes(CALLBACK_TYPES);
                            // 创建子类
                            return enhancer.createClass();
                        }
                        Object instance;
                        if (ctor == null) {
                            // 反射实例化对象,使用默认的构造方法
                            instance = BeanUtils.instantiateClass(subclass);
                        } else {
                            // 如果有指定参数的构造方法
                            Constructor<?> enhancedSubclassConstructor = subclass.getConstructor(ctor.getParameterTypes());
                            // 使用指定参数创建对象
                            instance = enhancedSubclassConstructor.newInstance(args);
                        }
                        // 生成的实例都是Factory的实例
                        Factory factory = (Factory) instance;
                        // 设置回调接口
                        factory.setCallbacks(new Callback[]{NoOp.INSTANCE,
                                // 处理@Lookup方法或者xml lookup方法的代理对象拦截器
                                new LookupOverrideMethodInterceptor(this.beanDefinition, this.owner),
                                // 处理xml中relace配置
                                new ReplaceOverrideMethodInterceptor(this.beanDefinition, this.owner)});
                        return instance;
                    }
                }
            }
        }
    }

    // 实例化@Bean方法返回的对象
    private Object instantiate(String beanName, RootBeanDefinition mbd, Object factoryBean, Method factoryMethod, Object[] args) {
        return this.beanFactory.getInstantiationStrategy().instantiate(mbd, beanName, this.beanFactory, factoryBean, factoryMethod, args)
        {
            // 反射执行方法
            ReflectionUtils.makeAccessible(factoryMethod);
            Object result = factoryMethod.invoke(factoryBean, args);
            return result;
        }
    }

    /**
     * 构造注入
     * @param explicitArgs 构造方法参数
     */
    public BeanWrapper autowireConstructor(String beanName, RootBeanDefinition mbd, Constructor<?>[] chosenCtors, Object[] explicitArgs) {
        // 创建BeanWrapperImpl
        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;
            // 这里目的就是获取已经处理过一次Bean对象的缓存信息
            synchronized (mbd.constructorArgumentLock) {
                // 获取解析过的构造方法或者@Bean方法
                constructorToUse = (Constructor<?>) mbd.resolvedConstructorOrFactoryMethod;
                // 如果之前就缓存解析好了构造方法,并且标记做了标记,已经被处理好
                if (constructorToUse != null && mbd.constructorArgumentsResolved) {
                    // 缓存时候存入的
                    // if (ArgumentsHolder.resolveNecessary) {
                    //	    mbd.preparedConstructorArguments = this.preparedArguments;
                    //	}
                    //	else {
                    //		mbd.resolvedConstructorArguments = this.arguments;
                    //	}
                    // 找到已经处理好的缓存的构造函数参数,要不在resolvedConstructorArguments,要不在preparedConstructorArguments中
                    argsToUse = mbd.resolvedConstructorArguments;
                    if (argsToUse == null) {
                        argsToResolve = mbd.preparedConstructorArguments;
                    }
                }
            }
            // 如果argsToResolve没有,表示构造函数从来没有处理过,没有被缓存
            if (argsToResolve != null) {
                // 提前解析构造参数,详见下面resolvePreparedArguments方法解析
                argsToUse = resolvePreparedArguments(beanName, mbd, bw, constructorToUse, argsToResolve, true) ''
            }
        }
        //  如果当前Bean的构造方法没有被缓存,或者该构造方法的参数没有被解析
        if (constructorToUse == null || argsToUse == null) {
            // 获取指定的构造函数
            Constructor<?>[] candidates = chosenCtors;
            // 如果没有传递指定的构造方法
            if (candidates == null) {
                // 获取类型
                Class<?> beanClass = mbd.getBeanClass();
                // 如果允许访问非public的构造方法,就获取所有的的,否则只获取public的构造方法
                candidates = (mbd.isNonPublicAccessAllowed() ? beanClass.getDeclaredConstructors() : beanClass.getConstructors());
            }
            // 如果只有一个构造方法,并且也没有指定参数,并且没有手动对BD设置构造参数
            // 因为这种条件最简单,也不需要对构造函数的参数进行解析,类型转换啥的
            if (candidates.length == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
                // 就使用这个构造方法
                Constructor<?> uniqueCandidate = candidates[0];
                // 如果是无参构造
                if (uniqueCandidate.getParameterCount() == 0) {
                    synchronized (mbd.constructorArgumentLock) {
                        // 缓存解析后的构造函数
                        mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
                        // 标记该Bean的构造参数已经解析完成了
                        mbd.constructorArgumentsResolved = true;
                        // 缓存已经解析好的构造参数,就是一个空数组
                        mbd.resolvedConstructorArguments = EMPTY_ARGS;
                    }
                    // 实例化,并保存到BeanWrapper中,实例化过程详见上面的instantiate方法,四个参数的
                    bw.setBeanInstance(instantiate(beanName, mbd, uniqueCandidate, EMPTY_ARGS));
                    // 返回包装好的对象
                    return bw;
                }
            }

            // 需要解析构造函数
            // 如果参数传递指定的构造函数,或者BD中设置了注入模式为构造注入,这个时候就需要使用构造注入
            // 只有两种情况会指定构造函数
            // 1. 只有当SmartInstantiationAwareBeanPostProcessor,determineConstructorsFromBeanPostProcessors后置处理器返回了指定要用的构造函数
            // 2. 在BD中,有重写getPreferredConstructors方法,并返回给定的构造函数
            // 其他情况,构造方法都是空的
            boolean autowiring = (chosenCtors != null || mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
            // 机场线到的构造参数值对象
            ConstructorArgumentValues resolvedValues = null;
            // 记录可用的构造参数的最小个数
            int minNrOfArgs;
            // 如果给定了
            if (explicitArgs != null) {
                minNrOfArgs = explicitArgs.length;
            } else {
                // 没有给定,获取存在BD中自己设置的构造参数值
                ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
                resolvedValues = new ConstructorArgumentValues();
                // 解析构造参数值,详见下面resolveConstructorArguments,并返回可用构造函数的最小参数个数
                minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
            }
            // 对可用的构造函数进行排序
            AutowireUtils.sortConstructors(candidates);
            // 遍历说中可用的构造方法
            for (Constructor<?> candidate : candidates) {
                // 获取参数个数
                int parameterCount = candidate.getParameterCount();
                // 如果已经有可用的方法,并且也有对应的可用参数,并且参数的个数可用的参数比实际的参数多
                // 表示这个构造方法已经可以用了,就不需要再找了
                if (constructorToUse != null && argsToUse != null && argsToUse.length > parameterCount) {
                    break;
                }
                // 如果当前构造方法的参数个数小于可用的构造函数中,最小参数个数的话的情况
                // 那表示当前构造方法肯定不满足,因为最小可用的构造方法个数都比你多,说明它不可用
                // 继续找下一个
                if (parameterCount < minNrOfArgs) {
                    continue;
                }
                // 创建一个参数的持有者,保存和各个阶段参数的集合,解析好的结合,未解析的集合
                ArgumentsHolder argsHolder;
                // 获取构造参数的所有类型
                Class<?>[] paramTypes = candidate.getParameterTypes();
                // 如果参数已经被解析过了
                if (resolvedValues != null) {
                    // 获取参数的名称
                    String[] paramNames = ConstructorPropertiesChecker.evaluate(candidate, parameterCount);
                    // 如果没有参数名称
                    if (paramNames == null) {
                        // 使用参数的本定变量表找
                        ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
                        if (pnd != null) {
                            paramNames = pnd.getParameterNames(candidate);
                        }
                    }
                    // 将解析好的参数封装成ArgumentsHolder对象,下面有方法解释
                    argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames, getUserDeclaredConstructor(candidate), autowiring, candidates.length == 1);
                }
                // 如果参数没有被解析
                // 表示给了构造参数
                else {
                    // 给定的构造参数和当前构造函数的参数不一样,表示不可用
                    if (parameterCount != explicitArgs.length) {
                        continue;
                    }
                    // 将参数封装成ArgumentsHolder对象
                    argsHolder = new ArgumentsHolder(explicitArgs){
                        // 解析之前原始参数,没有被解析过的值
                        this.rawArguments = args;
                        // 实际需要用的参数,只保存解析之后的值
                        this.arguments = args;
                        // 预处理的参数,可能解析完成,可能没有解析完成
                        this.preparedArguments = args;
                    }
                }
                // 比较权重,就是那个构造方法的参数集最符合要求
                int typeDiffWeight = (mbd.isLenientConstructorResolution() ? argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
                // 如果它表示最接近的匹配,则选择此构造函数。
                if (typeDiffWeight < minTypeDiffWeight) {
                    // 保存当前需要使用的构造方法
                    constructorToUse = candidate;
                    // 保存当前需要使用的参数持有者
                    argsHolderToUse = argsHolder;
                    // 需要使用的参数集
                    argsToUse = argsHolder.arguments;
                    // 再修改最小的符合条件的权重值,只有比当前这个更小才有资格被使用
                    minTypeDiffWeight = typeDiffWeight;
                    // 重置标记
                    // 这个标记是记录着如果有多个可用的构造方法,并且权重一样,下面就要根据条件是否要报错了
                    ambiguousConstructors = 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);
            }
            // 如果有多个可用的构造方法,并且权重一样,再看一下BD中是否设置要严格的解析构造函数,如果设置了严格,抛出异常
            else if (ambiguousConstructors != null && !mbd.isLenientConstructorResolution()) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName,ambiguousConstructors);
            }
            // 如果没有指定参数,并且参数已经被解析过了,有可用的参数集
            if (explicitArgs == null && argsHolderToUse != null) {
                // 缓存当前Bean的构造方法,以及参数信息
                argsHolderToUse.storeCache(mbd, constructorToUse){
                    synchronized (mbd.constructorArgumentLock) {
                        // 缓存构造方法,或者@Bean方法
                        mbd.resolvedConstructorOrFactoryMethod = constructorOrFactoryMethod;
                        // 标记为构造方法参数已经解析完成
                        mbd.constructorArgumentsResolved = true;
                        // 如果当前参数持有着被标记了需要被解析
                        if (this.resolveNecessary) {
                            // 那么就只能缓存提前准备好的参数,因为后面还要解析
                            mbd.preparedConstructorArguments = this.preparedArguments;
                        }
                        else {
                            // 否则保存已经解析完成的的参数
                            mbd.resolvedConstructorArguments = this.arguments;
                        }
                    }
                }
            }
        }

        // 如果BD中已经缓存了resolvedConstructorOrFactoryMethod构造方法或者@Bean方法,就可以直接实例化
        // 或者没有缓存,然后进行一些列的参数解析,找符合条件的构造方法,最终实例化对象
        bw.setBeanInstance(instantiate(beanName, mbd, constructorToUse, argsToUse));
        return bw;
    }


    /**
     * 实例化@Bean方法逻辑,其实@Bean方法的参数就是当做构造注入的形式来处理的,原理是一样的
     * 如果下面有说到构造参数,实际上就是@Bean方法参数
     * @param explicitArgs @Bean方法的参数
     */
    public BeanWrapper instantiateUsingFactoryMethod(String beanName, RootBeanDefinition mbd, Object[] explicitArgs) {
        // 创建BeanWrapperImpl
        BeanWrapperImpl bw = new BeanWrapperImpl();
        // 并初始化类型转换器
        this.beanFactory.initBeanWrapper(bw);
        // @Bean方法所在的对象
        Object factoryBean;
        // factoryBean的Class
        Class<?> factoryClass;
        // @Bean方法是不是静态的
        boolean isStatic;

        // 获取配置当前@Bean的对象的beanName
        String factoryBeanName = mbd.getFactoryBeanName();
        // 如果存在
        if (factoryBeanName != null) {
            // 如果@Bean方法所在的对象的BeanName和当前@Bean返回的Bean的beanName一样,就报错
            if (factoryBeanName.equals(beanName)) {
                throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
                        "factory-bean reference points back to the same bean definition");
            }
            // 获取配置该@Bean的对象,@Bean方法需要用到对象
            factoryBean = this.beanFactory.getBean(factoryBeanName);
            // 如果该Bean是单例,并且容器中已经存在该beanName对应的Bean,也报错
            if (mbd.isSingleton() && this.beanFactory.containsSingleton(beanName)) {
                throw new ImplicitlyAppearedSingletonException();
            }
            // 获取方法所属对象的类型
            factoryClass = factoryBean.getClass();
            // 标记非静态方法
            isStatic = false;
        }
        else {
            // 如果factoryBeanName为空,表是该方法是静态的
            // 如果Bd没有设置Class,抛出异常,因为最终反射还是需要用到Class
            if (!mbd.hasBeanClass()) {
                throw new BeanDefinitionStoreException(mbd.getResourceDescription(), beanName,
                        "bean definition declares neither a bean class nor a factory-bean reference");
            }
            // @bean静态方法不需要对象
            factoryBean = null;
            // 获取方法所属Bean的Class
            factoryClass = mbd.getBeanClass();
            // 标记为静态方法
            isStatic = true;
        }
        // 需要使用的@bean方法对象
        Method factoryMethodToUse = null;
        // @TODO
        // 方法需要使用的参数持有者对像
        ArgumentsHolder argsHolderToUse = null;
        // 执行@Bean方法需要的参数
        Object[] argsToUse = null;
        // 如果给定了@Bean方法的参数
        if (explicitArgs != null) {
            // 使用给定的方法参数
            argsToUse = explicitArgs;
        }
        else {
            // 需要解析的参数
            Object[] argsToResolve = null;
            // 这里目的就是获取已经处理过一次Bean对象的缓存信息
            synchronized (mbd.constructorArgumentLock) {
                // 获取解析过的@Bean方法
                factoryMethodToUse = (Method) mbd.resolvedConstructorOrFactoryMethod;
                // 如果之前就缓存解析好了,并且标记做了标记,已经被处理好
                if (factoryMethodToUse != null && mbd.constructorArgumentsResolved) {
                    // 缓存时候存入的
                    // if (ArgumentsHolder.resolveNecessary) {
                    //	    mbd.preparedConstructorArguments = this.preparedArguments;
                    //	}
                    //	else {
                    //		mbd.resolvedConstructorArguments = this.arguments;
                    //	}
                    // 找到已经处理好的缓存的方法参数,要不在resolvedConstructorArguments,要不在preparedConstructorArguments中
                    argsToUse = mbd.resolvedConstructorArguments;
                    if (argsToUse == null) {
                        argsToResolve = mbd.preparedConstructorArguments;
                    }

                }
            }
            // 如果argsToResolve没有,表示方法参数从来没有处理过,没有被缓存
            if (argsToResolve != null) {
                // 提前解析方法需要的参数,详见下面resolvePreparedArguments方法解析
                argsToUse = resolvePreparedArguments(beanName, mbd, bw, factoryMethodToUse, argsToResolve, true);
            }
        }
        //  如果当前Bean的方法没有被缓存,或者该方法参数没有被解析
        if (factoryMethodToUse == null || argsToUse == null) {
            // 获取对@Bean所属对象的自己的类,因为可能会被代理
            factoryClass = ClassUtils.getUserClass(factoryClass);
            // 可用的@bean方法
            List<Method> candidates = null;
            // 该@Bean是否是唯
            // 因为可能存在@Bean方法重载,参数不同
            // 在isOverriddenByExistingDefinition会处理这种情况,如果有存在在的@Bean方法重载它就不唯一
            // 表示该方法虽然beanName一样,但是实际上对应的方法不一样
            if (mbd.isFactoryMethodUnique) {
                // 使用解析好的方法对象
                if (factoryMethodToUse == null) {
                    factoryMethodToUse = mbd.getResolvedFactoryMethod();
                }
                // 保存成候选的方法candidates
                if (factoryMethodToUse != null) {
                    candidates = Collections.singletonList(factoryMethodToUse);
                }
            }
            // 如果没有找到候选的方法
            if (candidates == null) {
                candidates = new ArrayList<>();
                // 获取@bean方法对象中获取方法
                Method[] rawCandidates = getCandidateMethods(factoryClass, mbd);
                // 遍历所有的方法
                for (Method candidate : rawCandidates) {
                    // 找符合条件的的方法,isStatic上面就已经处理过了,即使是@Bean对应修饰符
                    // 如果遍历的所有方法中,和当前方法有着一样的修饰符,并且也是@Bean方法,就表示可以用
                    if (Modifier.isStatic(candidate.getModifiers()) == isStatic && mbd.isFactoryMethod(candidate)) {
                        candidates.add(candidate);
                    }
                }
            }
            // 方法只有一个,并且没有给定方法参数,BD中也没有设置方法参数
            // 就不需要解析方法参数
            if (candidates.size() == 1 && explicitArgs == null && !mbd.hasConstructorArgumentValues()) {
                // 获取到这个唯一的方法
                Method uniqueCandidate = candidates.get(0);
                // 如果方法不需要参数
                if (uniqueCandidate.getParameterCount() == 0) {
                    // 缓存该方法,表示该方法可以直接使用,不需要依赖注入
                    mbd.factoryMethodToIntrospect = uniqueCandidate;
                    // 缓存处理好的信息
                    synchronized (mbd.constructorArgumentLock) {
                        // 保存解析好的方法对象
                        mbd.resolvedConstructorOrFactoryMethod = uniqueCandidate;
                        // 标识已经解析好了参数
                        mbd.constructorArgumentsResolved = true;
                        // 解析好的参数为空数组
                        mbd.resolvedConstructorArguments = EMPTY_ARGS;
                    }
                    // 实例化,并保存到BeanWrapper中,实例化过程详见上面的instantiate方法,实例化@Bean方法的实现
                    bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, uniqueCandidate, EMPTY_ARGS));
                    return bw;
                }
            }
            // 如果存在@Bean方法的重载,方法名一样,方法参数不一样
            if (candidates.size() > 1)
                // 对两个@Bean进行排序
                // 优先比访问修饰符public,再比方法参数,方法参数多,则优先
                candidates.sort(AutowireUtils.EXECUTABLE_COMPARATOR);
            }
            // 解析的方法参数值
            ConstructorArgumentValues resolvedValues = null;
            // 获取当前Bean的注入模式是不是构造注入
            // @Bean方法都是构造注入
            boolean autowiring = (mbd.getResolvedAutowireMode() == AutowireCapableBeanFactory.AUTOWIRE_CONSTRUCTOR);
            // 最合适的@Bean方法的权重算法
            int minTypeDiffWeight = Integer.MAX_VALUE;
            // 保存多个可用的,但是无法选出独有的方法集合
            Set<Method> ambiguousFactoryMethods = null;
            // 记录可用的方法参数的最小个数
            int minNrOfArgs;
            // 如果给定了方法参数
            if (explicitArgs != null) {
                minNrOfArgs = explicitArgs.length;
            }
            else {
                // 没有给定,看对于BD是否添加了方法参数
                if (mbd.hasConstructorArgumentValues()) {
                    // 获取存在BD中自己设置的参数值
                    ConstructorArgumentValues cargs = mbd.getConstructorArgumentValues();
                    resolvedValues = new ConstructorArgumentValues();
                    // 解析方法参数值,详见下面resolveConstructorArguments,并返回可用方法函数的最小参数个数
                    minNrOfArgs = resolveConstructorArguments(beanName, mbd, bw, cargs, resolvedValues);
                }
                else {
                    // 如果没有方法参数
                    minNrOfArgs = 0;
                }
            }

            // 异常的集合
            LinkedList<UnsatisfiedDependencyException> causes = null;
            // 遍历所有可用的@Bean方法
            for (Method candidate : candidates) {
                // 获取方法的个数
                int parameterCount = candidate.getParameterCount();
                // 只有当前方法参数大于最小可用的参数的时候,才需要对参数进行解析
                // 因为当前方法参数都小于必要的参数个数,那该方法肯定是不能用的
                if (parameterCount >= minNrOfArgs) {
                    ArgumentsHolder argsHolder;
                    // 获取所有的参数类型
                    Class<?>[] paramTypes = candidate.getParameterTypes();
                    // 如果有给定方法参数
                    if (explicitArgs != null) {
                        // 但是当前方法的参数个不相同,表示这个方法不可用
                        if (paramTypes.length != explicitArgs.length) {
                            continue;
                        }
                        // 将参数封装成ArgumentsHolder对象
                        argsHolder = new ArgumentsHolder(explicitArgs){
                            // 解析之前原始参数,没有被解析过的值
                            this.rawArguments = args;
                                // 实际需要用的参数,只保存解析之后的值
                            this.arguments = args;
                                // 预处理的参数,可能解析完成,可能没有解析完成
                            this.preparedArguments = args;
                        }
                    }
                    // 没有给定方法参数
                    else {
                        String[] paramNames = null;
                        // 时候参数名解析器解析方法参数名
                        ParameterNameDiscoverer pnd = this.beanFactory.getParameterNameDiscoverer();
                        if (pnd != null) {
                            paramNames = pnd.getParameterNames(candidate);
                        }
                        // 将解析好的参数封装成ArgumentsHolder对象,下面有方法解释
                        argsHolder = createArgumentArray(beanName, mbd, resolvedValues, bw, paramTypes, paramNames, candidate, autowiring, candidates.size() == 1);
                    }

                    // 比较权重,就是那个方法的参数集最符合要求
                    int typeDiffWeight = (mbd.isLenientConstructorResolution() ? argsHolder.getTypeDifferenceWeight(paramTypes) : argsHolder.getAssignabilityWeight(paramTypes));
                    // 如果它表示最接近的匹配,则选择此方法
                    if (typeDiffWeight < minTypeDiffWeight) {
                        // 保存当前需要使用的方法
                        factoryMethodToUse = candidate;
                        // 保存当前需要使用的参数持有者
                        argsHolderToUse = argsHolder;
                        // 需要使用的参数集
                        argsToUse = argsHolder.arguments;
                        // 再修改最小的符合条件的权重值,只有比当前这个更小才有资格被使用
                        minTypeDiffWeight = typeDiffWeight;
                        // 重置标记
                        // 这个标记是记录着如果有多个可用的方法,并且权重一样,下面就要根据条件是否要报错了
                        ambiguousFactoryMethods = null;
                    }
                    // 如果上一次或上几次循环找到了可用的方法,并且和上次的权重一样,方法参数类型等等都一样
                    else if (factoryMethodToUse != null && typeDiffWeight == minTypeDiffWeight && !mbd.isLenientConstructorResolution() && paramTypes.length == factoryMethodToUse.getParameterCount() && !Arrays.equals(paramTypes, factoryMethodToUse.getParameterTypes())) {
                        // 这个标记是记录着如果有多个可用的方法,并且权重一样,下面就要根据条件是否要报错了
                        if (ambiguousFactoryMethods == null) {
                            ambiguousFactoryMethods = new LinkedHashSet<>();
                            ambiguousFactoryMethods.add(factoryMethodToUse);
                        }
                        // 保存重复的方法,下面需要校验报错
                        ambiguousFactoryMethods.add(candidate);
                    }
                }
            }
            // 如果找遍所有的方法都没有可用的方法,或者没有可用的参数
            if (factoryMethodToUse == null || argsToUse == null) {
                // 如果之前存在异常,继续压入异常栈中
                if (causes != null) {
                    UnsatisfiedDependencyException ex = causes.removeLast();
                    for (Exception cause : causes) {
                        this.beanFactory.onSuppressedException(cause);
                    }
                    throw ex;
                }
                // 如果之前不存在异常
                List<String> argTypes = new ArrayList<>(minNrOfArgs);
                // 如果指定的参数
                if (explicitArgs != null) {
                    // 遍历所有的参数
                    for (Object arg : explicitArgs) {
                        // 保存给定参数的类型
                        argTypes.add(arg != null ? arg.getClass().getSimpleName() : "null");
                    }
                }
                // 如果已经解析了方法参数指
                else if (resolvedValues != null) {
                    // 保存好所有解析后的参数值持有者对象
                    Set<ValueHolder> valueHolders = new LinkedHashSet<>(resolvedValues.getArgumentCount());
                    valueHolders.addAll(resolvedValues.getIndexedArgumentValues().values());
                    valueHolders.addAll(resolvedValues.getGenericArgumentValues());
                    // 遍历所有的持有者
                    for (ValueHolder value : valueHolders) {
                        // 保存参数值的类型
                        String argType = (value.getType() != null ? ClassUtils.getShortName(value.getType()) : (value.getValue() != null ? value.getValue().getClass().getSimpleName() : "null"));
                        argTypes.add(argType);
                    }
                }
                // 拼接参数类型
                String argDesc = StringUtils.collectionToCommaDelimitedString(argTypes);
                // 抛出错误信息
                throw new BeanCreationException(mbd.getResourceDescription(), beanName, "No matching factory method found: " );
            }
            // 如果有可用的方法,但是方法返回void,直接抛出异常
            else if (void.class == factoryMethodToUse.getReturnType()) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName, needs to have a non-void return type!");
            }
            // 如果存在多个同时可用的@Bean方法,也抛出异常,因为不知道用哪一个
            else if (ambiguousFactoryMethods != null) {
                throw new BeanCreationException(mbd.getResourceDescription());
            }
            // 如果没有给定方法参数,但是自己解析过参数
            if (explicitArgs == null && argsHolderToUse != null) {
                // 将当前使用的方法缓存
                mbd.factoryMethodToIntrospect = factoryMethodToUse;
                // 缓存参数
                argsHolderToUse.storeCache(mbd, factoryMethodToUse){
                    synchronized (mbd.constructorArgumentLock) {
                        // 缓存@Bean方法
                        mbd.resolvedConstructorOrFactoryMethod = constructorOrFactoryMethod;
                        // 标记为方法参数已经解析完成
                        mbd.constructorArgumentsResolved = true;
                        // 如果当前参数持有着被标记了需要被解析
                        if (this.resolveNecessary) {
                            // 那么就只能缓存提前准备好的参数,因为后面还要解析
                            mbd.preparedConstructorArguments = this.preparedArguments;
                        }
                        else {
                            // 否则保存已经解析完成的的参数
                            mbd.resolvedConstructorArguments = this.arguments;
                        }
                    }
                }
            }
        }
        // 如果BD中已经缓存了resolvedConstructorOrFactoryMethod构造方法或者@Bean方法,就可以直接实例化
        // 或者没有缓存,然后进行一些列的参数解析,找符合条件的方法,最终执行该方法
        bw.setBeanInstance(instantiate(beanName, mbd, factoryBean, factoryMethodToUse, argsToUse));
        return bw;
    }

    /**
     * 解析构造方法参数,这里就是在BD中设置的构造函数参数进行对应的值转换如果有必要,然后在使用转换后的参数创建对象
     */
    private int resolveConstructorArguments(String beanName, RootBeanDefinition mbd, BeanWrapper bw, ConstructorArgumentValues cargs, ConstructorArgumentValues resolvedValues) {

        // 获取自定义类型转换器
        TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
        // 如果不存在自定的,使用BeanWrapper包装器
        TypeConverter converter = (customConverter != null ? customConverter : bw);
        // 创建BDValue解析器
        BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converter);
        // 获取构造方法参数的个数,包括index设置的以及普通泛型的设置的
        int minNrOfArgs = cargs.getArgumentCount() {
            return (this.indexedArgumentValues.size() + this.genericArgumentValues.size());
        }
        // 遍历构造方法的所有键值对,先遍历按照Index设置的构造方法
        // 可以利用index-value来表示第几个构造参数为什么
        for (Map.Entry<Integer, ConstructorArgumentValues.ValueHolder> entry : cargs.getIndexedArgumentValues().entrySet()) {
            int index = entry.getKey();
            if (index < 0) {
                throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid constructor argument index: " + index);
            }
            // 动态更新符合条件构造方法的最小参数个数
            // 因为当前索引比给定的构造参数个数要大,就是单纯的记一下个数,也不会进行索引校验
            // 外面会根据这个数量来对不满足(小于)构造参数的的数量进行过滤
            if (index > minNrOfArgs) {
                minNrOfArgs = index + 1;
            }
            // 获取构造函数值
            ConstructorArgumentValues.ValueHolder valueHolder = entry.getValue();
            // 如果值已经类型转换成功了
            if (valueHolder.isConverted()) {
                // 将类型转换后的值重新放回去
                resolvedValues.addIndexedArgumentValue(index, valueHolder);
            } else {
                // 如果没解析好,使用值解析器进行解析
                // 就是可能给定的值是beanName,是占位符,或者可能是BD
                // 会处理以下类型
                //  RuntimeBeanReference -> <bean ref=''/>
                //  RuntimeBeanNameReference
                //  BeanDefinitionHolder
                //  BeanDefinition
                //  DependencyDescriptor(依赖注入引用的bean对应的操作类)
                //  ManagedArray,ManagedList,ManagedSet,ManagedMap,ManagedProperties,TypedStringValue
                //  将最终的值转换为Bean对象,实际上这些多数是在Xml中配置的属性对应成解析到的类
                /**
                 * 案例:
                 * <pre>
                 *      RootBeanDefinition bd = new RootBeanDefinition();
                 *      ConstructorArgumentValues values = bd.getConstructorArgumentValues();
                 *      // 如果我这里要的b实际上是一个Bean的BeanName呢?我们这样设置的"b"只会当成一个值
                 *      // 如果要当成一个Bean呢,就和xml中配置的ref一样,它最终会生成一个对象
                 *      // 所以,可以修改成这样,RuntimeBeanReference表示对BeanName为b的引用,RuntimeBeanNameReference表示对beanName为c的动态引用
                 *      // RuntimeBeanReference和RuntimeBeanNameReference区别是,前者是立刻解析好beanName对应的bean进行引用
                 *      // 而后者是存的一致是beanName,要用到的时候,在通过BeanName去引用容器中的Bean,其实都差不多
                 *      // bd.getConstructorArgumentValues().addIndexedArgumentValue(1, new RuntimeBeanReference("b"));
                 *      // bd.getConstructorArgumentValues().addIndexedArgumentValue(2, new RuntimeBeanNameReference("c"));
                 *      values.addIndexedArgumentValue(1, "b");
                 *      bd.setBeanClass(F.class);
                 *      registry.registerBeanDefinition("f", bd);
                 * </pre>
                 */
                Object resolvedValue = valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue());
                // 封装成ValueHolder对象
                ConstructorArgumentValues.ValueHolder resolvedValueHolder = new ConstructorArgumentValues.ValueHolder(resolvedValue, valueHolder.getType(), valueHolder.getName());
                // 将解析后类型转换后的值重新放回去
                resolvedValueHolder.setSource(valueHolder);
                resolvedValues.addIndexedArgumentValue(index, resolvedValueHolder);
            }
        }

        // 遍历普通泛型设置的构造参数,和上面一样
        for (ConstructorArgumentValues.ValueHolder valueHolder : cargs.getGenericArgumentValues()) {
            // 如果值已经类型转换成功了
            if (valueHolder.isConverted()) {
                // 将类型转换后的值重新放回去
                resolvedValues.addGenericArgumentValue(valueHolder);
            } else {
                // 如果没解析好,使用值解析器进行解析
                // 就是可能给定的值是beanName,是占位符,可能是Bean的依赖关系,或者可能是BD
                // 将最终的值转换为Bean对象,上面有案例
                Object resolvedValue = valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue());
                // 封装成ValueHolder对象
                ConstructorArgumentValues.ValueHolder resolvedValueHolder = new ConstructorArgumentValues.ValueHolder(resolvedValue, valueHolder.getType(), valueHolder.getName());
                // 将解析后类型转换后的值重新放回去
                resolvedValueHolder.setSource(valueHolder);
                resolvedValues.addGenericArgumentValue(resolvedValueHolder);
            }
        }
        // 返回
        return minNrOfArgs;
    }

    /**
     * 创建构造函数/或者@Bean方法的参数集合,如果是@Bean方法,构造参数指的就是方法参数
     * 因为方法参数和构造方法参数一样,都是需要立即注入的
     */
    private ArgumentsHolder createArgumentArray(String beanName, RootBeanDefinition mbd, ConstructorArgumentValues resolvedValues, BeanWrapper bw, Class<?>[] paramTypes, String[] paramNames, Executable executable, boolean autowiring, boolean fallback) {
        // 自定义的类型转换器
        TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
        // 确定需要使用的类型转换器
        TypeConverter converter = (customConverter != null ? customConverter : bw);
        // 创建一个参数的持有者
        // 下面所谓的解析,就是类型转换,根据给定的参数值转换成实际的需要的值
        ArgumentsHolder args = new ArgumentsHolder(paramTypes.length) {
            // 解析之前原始参数,没有被解析过的值
            public final Object[] rawArguments;
            // 实际需要用的参数,只保存解析之后的值
            public final Object[] arguments;
            // 预处理的参数,可能解析完成,可能没有解析完成
            public final Object[] preparedArguments;
            // 标记当前参数集合的值是否需要解析
            public boolean resolveNecessary = false;
        }
        // 需要使用到的构造参数集合
        Set<ConstructorArgumentValues.ValueHolder> usedValueHolders = new HashSet<>(paramTypes.length);
        // 需要注入的beanName
        Set<String> autowiredBeanNames = new LinkedHashSet<>(4);
        // 遍历所有的参数
        for (int paramIndex = 0; paramIndex < paramTypes.length; paramIndex++) {
            // 获取参数类型
            Class<?> paramType = paramTypes[paramIndex];
            // 如果没有,使用""
            String paramName = (paramNames != null ? paramNames[paramIndex] : "");
            // 尝试查找匹配的构造函数参数值,无论是索引的还是泛型的
            ConstructorArgumentValues.ValueHolder valueHolder = null;
            // 如果传递了解析好的构造函数集合
            if (resolvedValues != null) {
                // 遍历所有的构造函数值,找到一个符合条件的值对象
                // 根据参数索引,参数类型和参数名称获取对应的构造参数值
                // usedValueHolders是一个过滤作用,已经保存过的就直接跳过
                // 先从indexedArgumentValues找,再从genericArgumentValues中
                valueHolder = resolvedValues.getArgumentValue(paramIndex, paramType, paramName, usedValueHolders);
                // 如果没有找到合适类型的参数值,并且不是构造注入的情况下,或者参数个数匹配
                if (valueHolder == null && (!autowiring || paramTypes.length == resolvedValues.getArgumentCount())) {
                    // 不限制索引和参数类型再找一次,从genericArgumentValues找,因为可能存在泛型
                    valueHolder = resolvedValues.getGenericArgumentValue(null, null, usedValueHolders);
                }
            }
            // 如果找到了
            if (valueHolder != null) {
                // 保存找到过的参数值
                usedValueHolders.add(valueHolder);
                // 保存原始值
                Object originalValue = valueHolder.getValue();
                // 转换后的值
                Object convertedValue;
                // 如果值已经进行了类型转换了
                if (valueHolder.isConverted()) {
                    // 获取转换后的值
                    convertedValue = valueHolder.getConvertedValue();
                    // 这种情况,convertedValue已经解析完成了,保存到preparedArguments变量中
                    // preparedArguments变量保存的可能是解析完成的值,或者未解析完成的值
                    // 确保preparedArguments参数个数与所有的参数个数一致,所以,解析好的值也保存到这里
                    // 下面还有其他情况,就是值未被解析完成,只能保存到这preparedArguments
                    args.preparedArguments[paramIndex] = convertedValue;
                } else {
                    // 如果没有转换过
                    // 获取到构造方法
                    MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex);
                    // 使用类型转换器将原始值转换
                    convertedValue = converter.convertIfNecessary(originalValue, paramType, methodParam);
                    // 获取解析之前值的持有者
                    Object sourceHolder = valueHolder.getSource();
                    // 如果类型是构造参数的值的话
                    if (sourceHolder instanceof ConstructorArgumentValues.ValueHolder) {
                        // 获取到解析之前对应的值
                        // 在这之前,解析构造函数参数的时候,会做一件事,使用BeanDefinitionValueResolver解析ref,list这行属性,然后得到解析之后的值
                        // 但是这个值还没有进行类型转换,要看resolveConstructorArguments方法就明白
                        Object sourceValue = ((ConstructorArgumentValues.ValueHolder) sourceHolder).getValue();
                        // 标记这个参数args:ArgumentsHolder需要进行解析
                        args.resolveNecessary = true;
                        // sourceValue是未解析的值,所以它只能将值保存到preparedArguments中,preparedArguments是保存未完成最终解析(最终可用参数)的值
                        args.preparedArguments[paramIndex] = sourceValue;
                    }
                }
                // 保存解析后的值,arguments这个变量是保存所有解析之后,可用的值
                args.arguments[paramIndex] = convertedValue;
                // 这个变量是保存了未被解析的原始值
                args.rawArguments[paramIndex] = originalValue;
            }
            // 如果没有找到符合条件的构造参数
            else {
                // 获取到构造方法
                MethodParameter methodParam = MethodParameter.forExecutable(executable, paramIndex);
                // 如果当前注入方式不是构造注入的话,就抛出异常
                // 说白了就是没有找到构造方法指定索引下对应的的值,然后又不是构造注入,所以也不会去容器中找Bean
                // 所以这个构造方法就没办法创建对象了
                if (!autowiring) {
                    throw new UnsatisfiedDependencyException(mbd.getResourceDescription(), beanName, new InjectionPoint(methodParam));
                }
                try {
                    // 解析需要注入的参数,见下面resolveAutowiredArgument方法解析
                    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);
                }
            }
        }
        // 遍历需要注入的beanName
        for (String autowiredBeanName : autowiredBeanNames) {
            // 注册Beand的依赖关系
            this.beanFactory.registerDependentBean(autowiredBeanName, beanName);
        }
        // 返回解析好的参数持有者
        return args;
    }

    /**
     * 将给定的构造函数参数进行提前解析
     */
    private Object[] resolvePreparedArguments(String beanName, RootBeanDefinition mbd, BeanWrapper bw, Executable executable, Object[] argsToResolve, boolean fallback) {
        // 获取自定义类型转换器
        TypeConverter customConverter = this.beanFactory.getCustomTypeConverter();
        TypeConverter converter = (customConverter != null ? customConverter : bw);
        // 创建BDValue解析器
        BeanDefinitionValueResolver valueResolver = new BeanDefinitionValueResolver(this.beanFactory, beanName, mbd, converter);
        // 所有构造函数的所有参数类型
        Class<?>[] paramTypes = executable.getParameterTypes();
        // 解析之后的参数值
        Object[] resolvedArgs = new Object[argsToResolve.length];
        // 遍历所有的参数
        for (int argIndex = 0; argIndex < argsToResolve.length; argIndex++) {
            // 获取需要被解析的值
            Object argValue = argsToResolve[argIndex];
            // 创建方法参数对象
            MethodParameter methodParam = MethodParameter.forExecutable(executable, argIndex);
            // 	private static final Object autowiredArgumentMarker = new Object();
            // 如果值为一个标记值,表示这需要对这个值进行注入解析
            if (argValue == autowiredArgumentMarker) {
                // 解析需要注入的参数,见下面resolveAutowiredArgument方法解析
                argValue = resolveAutowiredArgument(methodParam, beanName, null, converter, fallback);
            }
            // 如果参数为Bean元素,ValueHolder,AbstractBeanDefinition等等都是这种类型
            if (argValue instanceof BeanMetadataElement) {
                // 使用值解析器进行解析,上面有解析
                argValue = valueResolver.resolveValueIfNecessary("constructor argument", argValue);
            }
            // 如果为String类型,解析一下SPEL表达式
            if (argValue instanceof String) {
                argValue = this.beanFactory.evaluateBeanDefinitionString((String) argValue, mbd);
            }
            // 获取参数类型
            Class<?> paramType = paramTypes[argIndex];
            // 对解析后的值进行类型转换
            resolvedArgs[argIndex] = converter.convertIfNecessary(argValue, paramType, methodParam);
        }
        // 返回主让后的值
        return resolvedArgs;
    }

    /**
     * 获取用户可以的构造方法,用于获取用户实际类的构造方法,因为类可能被代理
     */
    protected Constructor<?> getUserDeclaredConstructor(Constructor<?> constructor) {
        // 获取类
        Class<?> declaringClass = constructor.getDeclaringClass();
        // 获取实际类型,因为可能经过代理了
        Class<?> userClass = ClassUtils.getUserClass(declaringClass);
        // 如果类被代理了
        if (userClass != declaringClass) {
            // 获取实际类指定参数的构造方法
            return userClass.getDeclaredConstructor(constructor.getParameterTypes());
        }
        return constructor;
    }


    /**
     * 解析注入的参数
     */
    protected Object resolveAutowiredArgument(MethodParameter param, String beanName, Set<String> autowiredBeanNames, TypeConverter typeConverter, boolean fallback) {
        // 获取参数类型
        Class<?> paramType = param.getParameterType();
        // 如果参数是InjectionPoint注入点类型
        // 表示当前该类正在被注入的过程中
        if (InjectionPoint.class.isAssignableFrom(paramType)) {
            // 获取当前正在注入的类
            InjectionPoint injectionPoint = currentInjectionPoint.get();
            if (injectionPoint == null) {
                throw new IllegalStateException("No current InjectionPoint available for " + param);
            }
            // 直接返回正在注入的这个类就行了
            return injectionPoint;
        }
        // 使用工厂解析这个需要注入的Bean,详见@Autowired,@Resource,@Value注入的核心逻辑原理
        // DependencyDescriptor就是一个注入点InjectionPoint类型,在注入之前,解析该Bean的情况下
        // 会将执行InjectionPoint previousInjectionPoint = ConstructorResolver.setCurrentInjectionPoint(descriptor);
        // 将当前注入点保存起来,表示当前bean正在被解析
        return this.beanFactory.resolveDependency(new DependencyDescriptor(param, true), beanName, autowiredBeanNames, typeConverter);
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值