Spring源码分析(十一)依赖注入源码解析4:DefaultListableBeanFactory#findAutowireCandidates 根据类型查找所有候选Bean

2023-11-16

根据类型查找所有候选Bean

org.springframework.beans.factory.support.DefaultListableBeanFactory#findAutowireCandidates

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

    //1. 从BeanFactory中找出和requiredType所匹配的beanName,仅仅是beanName,这些bean不一定经过了实例化
    //descriptor.isEager():返回此依赖项是否为“急切的”,即急切地解析潜在的目标bean以进行类型匹配。
    //处理比如FactoryBean的情况,真正的类型肯定不是FactoryBean.class
    //所以获取真正的类型,就会需要初始化FactoryBean
    String[] candidateNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
            this, requiredType, true, descriptor.isEager());
    Map<String, Object> result = CollectionUtils.newLinkedHashMap(candidateNames.length);

    //2. 根据类型从resolvableDependencies中匹配,resolvableDependencies中存放的是 类型:bean对象
    //类似一个缓存,在Spring启动的时候会赋值
    //事先指定 类型 和 实例 的映射关系,只要是注入这个类型,就用这个类型对应的实例进行注入
    for (Map.Entry<Class<?>, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {
        Class<?> autowiringType = classObjectEntry.getKey();
        //requiredType如果是autowiringType子类 或 本身
        if (autowiringType.isAssignableFrom(requiredType)) {
            Object autowiringValue = classObjectEntry.getValue();
            //根据给定的所需类型解析给定的自动装配值,例如ObjectFactory值到其实际对象结果。
            autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
            if (requiredType.isInstance(autowiringValue)) {
                //满足条件,往结果集添加
                //这种方式bean是没有名字的,所以要利用ObjectUtils.identityToString生成
                result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
                break;
            }
        }
    }
    
    //从所匹配的beanName中继续过滤判断,能不能自动注入
    for (String candidate : candidateNames) {
        //3. isSelfReference:判断是不是自己注入自己
        //4. isAutowireCandidate:判断能不能注入
        if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, descriptor)) {
            //5.添加到结果集
            addCandidateEntry(result, candidate, descriptor, requiredType);
        }
    }
    // 为空要么是真的没有匹配的,要么是匹配的自己
    if (result.isEmpty()) {
        // 是否是多匹配,即需要匹配的类型是不是Map、数组、集合之类的
        boolean multiple = indicatesMultipleBeans(requiredType);
        // Consider fallback matches if the first pass failed to find anything...
        // 如果第一次传递找不到任何东西,请考虑回退匹配。。。
        // 6.回退匹配
        DependencyDescriptor fallbackDescriptor = descriptor.forFallbackMatch();
        for (String candidate : candidateNames) {
            //3. isSelfReference:判断是不是自己注入自己
            //4. isAutowireCandidate:判断能不能注入,回退匹配
            if (!isSelfReference(beanName, candidate) && isAutowireCandidate(candidate, fallbackDescriptor) &&
                    (!multiple || getAutowireCandidateResolver().hasQualifier(descriptor))) {
                //5.回退匹配成功,添加到结果集
                addCandidateEntry(result, candidate, descriptor, requiredType);
            }
        }
        //还是没有匹配成功的,尝试匹配自己
        if (result.isEmpty() && !multiple) {
            // Consider self references as a final pass...
            // but in the case of a dependency collection, not the very same bean itself.
            // 将自引用视为最后一次传递……但在依赖项集合的情况下,不是同一个bean本身。
            for (String candidate : candidateNames) {
                //3. isSelfReference:判断是不是自己注入自己
                if (isSelfReference(beanName, candidate) &&
                        (!(descriptor instanceof MultiElementDescriptor) || !beanName.equals(candidate)) &&
                    	//4. isAutowireCandidate:判断能不能注入,自己注入自己的情况
                        isAutowireCandidate(candidate, fallbackDescriptor)) {
                    //5.添加到结果集
                    addCandidateEntry(result, candidate, descriptor, requiredType);
                }
            }
        }
    }
    return result;
}

1. 从BeanFactory中找出和requiredType所匹配的beanName

从BeanFactory中找出和required所匹配的beanName,仅仅是beanName,这些bean不一定经过了实例化
org.springframework.beans.factory.BeanFactoryUtils#beanNamesForTypeIncludingAncestors(org.springframework.beans.factory.ListableBeanFactory, java.lang.Class<?>, boolean, boolean)

public static String[] beanNamesForTypeIncludingAncestors(
        ListableBeanFactory lbf, Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {
	//includeNonSingletons:是否也包含原型bean或作用域bean,还是只包含单例bean(也适用于FactoryBeans)
    //此时includeNonSingletons=true
    
    Assert.notNull(lbf, "ListableBeanFactory must not be null");
    //从本容器中找
    String[] result = lbf.getBeanNamesForType(type, includeNonSingletons, allowEagerInit);
    //从父容器找并放入result
    if (lbf instanceof HierarchicalBeanFactory) {
        HierarchicalBeanFactory hbf = (HierarchicalBeanFactory) lbf;
        if (hbf.getParentBeanFactory() instanceof ListableBeanFactory) {
            String[] parentResult = beanNamesForTypeIncludingAncestors(
                    (ListableBeanFactory) hbf.getParentBeanFactory(), type, includeNonSingletons, allowEagerInit);
            //合并父容器的结果
            result = mergeNamesWithParent(result, parentResult, hbf);
        }
    }
    return result;
}

lbf.getBeanNamesForType实现在:
org.springframework.beans.factory.support.DefaultListableBeanFactory#getBeanNamesForType(java.lang.Class<?>, boolean, boolean)

public String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) {
    //如果没有冻结,就根据类型去BeanFactory找,如果冻结了,可能就跳过这个if然后去缓存中去拿了
    //configurationFrozen:是否可以为所有bean  缓存  bean定义元数据。
    if (!isConfigurationFrozen() || type == null || !allowEagerInit) {
        return doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, allowEagerInit);
    }
	//从缓存取
    //includeNonSingletons:是否也包含原型bean或作用域bean,还是只包含单例bean(也适用于FactoryBeans)
    //此时true,所有
    Map<Class<?>, String[]> cache =
            (includeNonSingletons ? this.allBeanNamesByType : this.singletonBeanNamesByType);
    String[] resolvedBeanNames = cache.get(type);
    if (resolvedBeanNames != null) {
        return resolvedBeanNames;
    }
    //缓存没有再次加载
    resolvedBeanNames = doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, true);
    if (ClassUtils.isCacheSafe(type, getBeanClassLoader())) {
        //缓存
        cache.put(type, resolvedBeanNames);
    }
    return resolvedBeanNames;
}

注意,ResolvableType.forRawClass(type),当前链路把class的泛型去掉了,只会对原始类进行可分配性检查

简单来说接下来匹配不会考虑泛型。

//返回指定Class的ResolvableType,仅对原始类进行可分配性检查
public static ResolvableType forRawClass(@Nullable Class<?> clazz) {
    return new ResolvableType(clazz) {
        @Override
        public ResolvableType[] getGenerics() {
            //这里去掉了泛型的情况!!
            return EMPTY_TYPES_ARRAY;
        }
        @Override
        public boolean isAssignableFrom(Class<?> other) {
            //isAssignable:检查右侧类型是否可以分配给左侧类型
            return (clazz == null || ClassUtils.isAssignable(clazz, other));
        }
        @Override
        public boolean isAssignableFrom(ResolvableType other) {
            Class<?> otherClass = other.resolve();
            return (otherClass != null && (clazz == null || ClassUtils.isAssignable(clazz, otherClass)));
        }
    };
}

核心doGetBeanNamesForType

注意入参allowEagerInit的含义:

是否允许急切初始化:为类型检查,是否初始化 懒加载的单例Bean对象 和 由FactoryBeans(或由带有“factory-bean”引用的工厂方法)创建的对象。请注意,factorybean需要紧急初始化以确定它们的类型:因此请注意,为该标志传入“true”将初始化factorybean和“factory-bean”引用。

private String[] doGetBeanNamesForType(ResolvableType type, boolean includeNonSingletons, boolean allowEagerInit) {
    List<String> result = new ArrayList<>();

    // Check all bean definitions.
    // 遍历所有BeanDefinition的名字(beanDefinitionNames不会包含"&xxx"的)
    for (String beanName : this.beanDefinitionNames) {
        // Only consider bean as eligible if the bean name is not defined as alias for some other bean.
        // 只有当bean名称没有定义为其他bean的别名时,才认为bean是合格的。
        if (!isAlias(beanName)) {//只处理规范的BeanName
            try {
                //拿到合并后的RootBeanDefinition
                RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                // Only check bean definition if it is complete.
                //1.1 判断mbd允不允许解析对应的类型
                //首先mdb不能是抽象的
                
                //然后allowEagerInit为true,说明允许立即初始化,那接下来就去推测解析mdb的类型,并进行匹配
                //如果allowEagerInit为false,说明不允许立即初始化,但出现以下情况也可以继续去推测类型:
                
                // 需要同时满足a和b:
                //	a.以下三个条件满足其一:
                //		mbd.hasBeanClass():是否已经加载过类了
                //		mbd.isLazyInit():返回该bean是否应该延迟初始化,即在启动时不急于实例化。只适用于单例bean。(是不是懒加载的)
                //		isAllowEagerClassLoading():返回是否允许工厂紧急加载bean类,即使对于标记为“lazy-init”的bean定义也是如此。
                //		
                //		即已经加载过类、或者非懒加载的mdb、或者工厂允许紧急加载bean类
                
                //	b.requiresEagerInitForType:检查指定的bean是否需要紧急初始化以确定其类型。
                //	什么情况需要紧急初始化?当前beanName是FactoryBean,且FactoryBean本身还没有实例化的时候
                if (!mbd.isAbstract() && (allowEagerInit ||
                        (mbd.hasBeanClass() || !mbd.isLazyInit() || isAllowEagerClassLoading()) &&
                                !requiresEagerInitForType(mbd.getFactoryBeanName()))) {
                    
                    boolean isFactoryBean = isFactoryBean(beanName, mbd);
                    BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
                    boolean matchFound = false;
                    //是否允许FactoryBean初始化
                    //containsSingleton(beanName)=true,说明之前已经初始化过了
                    boolean allowFactoryBeanInit = (allowEagerInit || containsSingleton(beanName));
                    //是否是非懒加载的
                    boolean isNonLazyDecorated = (dbd != null && !mbd.isLazyInit());

                    //当前BeanDefinition不是FactoryBean,就是普通Bean
                    if (!isFactoryBean) {
                        //在筛选Bean时,如果仅仅只包括单例,但是BeanName对应的又不是单例,则会忽略
                        if (includeNonSingletons || isSingleton(beanName, mbd, dbd)) {
                            //1.2 类型匹配
                            matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
                        }
                    }
                    //FactoryBean情况:
                    else {
                        //includeNonSingletons:是否也包含原型bean或作用域bean,还是只包含单例bean(也适用于FactoryBeans)
                        //isNonLazyDecorated:是否是非懒加载的
                        //允许FactoryBean初始化并且BeanName对应的是单例

						//常规引用匹配,先尝试匹配FactoryBean背后真正的类型
                        if (includeNonSingletons || isNonLazyDecorated ||
                                (allowFactoryBeanInit && isSingleton(beanName, mbd, dbd))) {
                            //1.2 类型匹配
                            matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
                        }
                        //如果匹配失败,进行FactoryBean引用匹配
                        //有可能type是FactoryBean本身的类型,希望匹配的是FactoryBean自己的实例
                        if (!matchFound) {
                            // In case of FactoryBean, try to match FactoryBean instance itself next.
                            // 对于FactoryBean,接下来尝试匹配FactoryBean实例本身
                            beanName = FACTORY_BEAN_PREFIX + beanName;
                            if (includeNonSingletons || isSingleton(beanName, mbd, dbd)) {
                                //1.2 类型匹配
                                matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
                            }
                        }
                    }
                    if (matchFound) {
                        //匹配成功添加到结果集
                        result.add(beanName);
                    }
                }
            }
            catch (CannotLoadBeanClassException | BeanDefinitionStoreException ex) {...}
            catch (NoSuchBeanDefinitionException ex) {...}
        }
    }

    // Check manually registered singletons too.
    // 还要检查手动注册的单例
    for (String beanName : this.manualSingletonNames) {
        try {
            // In case of FactoryBean, match object created by FactoryBean.
            if (isFactoryBean(beanName)) {
                //处理FactoryBean的情况

                //常规引用匹配
                if ((includeNonSingletons || isSingleton(beanName)) && isTypeMatch(beanName, type)) {//1.2 类型匹配 isTypeMatch
                    result.add(beanName);
                    // Match found for this bean: do not match FactoryBean itself anymore.
                    // 为该bean找到匹配:不再匹配FactoryBean本身。
                    continue;
                }
                //FactoryBean引用匹配
                // In case of FactoryBean, try to match FactoryBean itself next.
                // 对于FactoryBean,接下来尝试匹配FactoryBean实例本身
                beanName = FACTORY_BEAN_PREFIX + beanName;
            }
            // Match raw bean instance (might be raw FactoryBean).
            // 匹配原始bean实例(可能是原始FactoryBean)。

            //1.2 类型匹配
            if (isTypeMatch(beanName, type)) {
                result.add(beanName);
            }
        }
        catch (NoSuchBeanDefinitionException ex) {...}
    }
	//最终返回一个结果
    return StringUtils.toStringArray(result);
}

1.1 判断BeanDefinition允不允许解析对应的类型

有一段复杂的判断逻辑:
在这里插入图片描述

首先mdb不能是抽象的。
其次要知道,allowEagerInit的含义:

  • 为了类型检查,是否初始化 懒加载的单例Bean对象 和 由FactoryBeans (或由带有“factory-bean”引用的工厂方法)创建的对象。请注意,factorybean需要紧急初始化以确定它们的类型:因此请注意,为该标志传入“true”将初始化factorybean和“factory-bean”引用。

如果allowEagerInit为true,说明允许立即初始化,那接下来就去推测解析mdb的类型。
如果allowEagerInit为false,说明不允许立即初始化,但出现以下情况也可以继续去推测类型,需要同时满足a和b:

  • a. 三个条件中先满足任意一个:

    • mbd.hasBeanClass():是否已经加载过类了
    • mbd.isLazyInit():返回该bean是否应该延迟初始化,即在启动时不急于实例化。只适用于单例bean。
    • isAllowEagerClassLoading():返回是否允许工厂紧急加载bean类,即使对于标记为“lazy-init”的bean定义也是如此。

      (mbd.hasBeanClass() || !mbd.isLazyInit() || isAllowEagerClassLoading()),即代表:已经加载过类、或者是非懒加载的bean、或者工厂允许紧急加载bean类
  • b. requiresEagerInitForType:检查指定的bean是否需要紧急初始化以确定其类型。

    !requiresEagerInitForType,代表不需要,大部分情况都是不需要的
    那什么情况需要紧急初始化?当前beanName是FactoryBean,且FactoryBean本身还没有实例化

org.springframework.beans.factory.support.DefaultListableBeanFactory#requiresEagerInitForType

private boolean requiresEagerInitForType(@Nullable String factoryBeanName) {
    //如果是FactoryBean情况,FactoryBean本身如果还没有初始化过,会返回true
    return (factoryBeanName != null && isFactoryBean(factoryBeanName) && !containsSingleton(factoryBeanName));
}

整个条件看上去有点复杂,但是如果只是考虑大部分流程,则可以忽略这个判断,因为allowEagerInit传进来的基本上都是true

1.2 类型匹配

org.springframework.beans.factory.support.AbstractBeanFactory#isTypeMatch(java.lang.String, org.springframework.core.ResolvableType, boolean)

//判断name所对应的Bean类型是不是typeToMatch,name有可能是&xxx工厂引用
protected boolean isTypeMatch(String name, ResolvableType typeToMatch, boolean allowFactoryBeanInit)
        throws NoSuchBeanDefinitionException {
    //allowFactoryBeanInit表示允不允许在这里实例化FactoryBean的对象,以获取真正的类型

    //获取规范的BeanName,如果name是&xxx,那beanName就是xxx
    String beanName = transformedBeanName(name);
    //判断name是不是对FactoryBean工厂引用(判断name是不是&开头)
    boolean isFactoryDereference = BeanFactoryUtils.isFactoryDereference(name);

    // Check manually registered singletons.
    // 先尝试从单例池直接获取bean实例
    Object beanInstance = getSingleton(beanName, false);
    if (beanInstance != null && beanInstance.getClass() != NullBean.class) {
        //单例池获取成功,说明这个Bean已经实例化过了
        if (beanInstance instanceof FactoryBean) {
            //拿到实例是FactoryBean情况
            if (!isFactoryDereference) {
                //常规引用,希望拿到是FactoryBean背后真实对象的类型
                //而FactoryBean本身已经实例化了,所以直接调用factoryBean.getObjectType拿到类型
                
                //a.获取FactoryBean创建的对象类型
                Class<?> type = getTypeForFactoryBean((FactoryBean<?>) beanInstance);
                return (type != null && typeToMatch.isAssignableFrom(type));
            }
            else {
                //FactoryBean引用,希望拿到FactoryBean本身的类型进行匹配
                return typeToMatch.isInstance(beanInstance);
            }
        }
        //单例池拿到的不是FactoryBean,并且是常规引用,希望获取真实对象类型进行匹配
        else if (!isFactoryDereference) {
            //直接匹配实例
            if (typeToMatch.isInstance(beanInstance)) {
                // Direct match for exposed instance?
                // 直接匹配公开的实例
                return true;
            }
            //直接匹配实例没成功,判断参数类型是不是带泛型,如果是会特殊处理
            //b.泛型可能仅在目标类上匹配,而在代理上不匹配
            //jdk动态代理+泛型的时候,泛型可能仅在目标类上匹配,而在代理上不匹配
            //typeToMatch.hasGenerics():如果此类型包含泛型参数则返回true。
            else if (typeToMatch.hasGenerics() && containsBeanDefinition(beanName)) {
                // Generics potentially only match on the target class, not on the proxy...
                // 泛型可能仅在目标类上匹配,而在代理(代理实例)上不匹配
                
                RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                //从BeanDefinition上获取目标类型(获取的是提前指定的目标类型,或是第一次实例化时解析的类型)
                //有可能为null,说明是工厂方法的情况
                Class<?> targetType = mbd.getTargetType();

                //targetType不为null的话,和实例类型进行比较,不一样,说明可能是jdk动态代理的实例
                //ClassUtils.getUserClass(beanInstance):返回给定实例的用户定义类:通常只是给定实例的类,但如果是CGLIB生成的子类,则返回原始类。
                if (targetType != null && targetType != ClassUtils.getUserClass(beanInstance)) {
                    // Check raw class match as well, making sure it's exposed on the proxy.
                    // 同时检查原始类匹配,确保它在代理上公开
                    // 此时beanInstance应该是一个jdk动态代理的对象

                    //typeToMatch.resolve:将类型解析为Class
                    //如果无法解析该类型,则返回null。
                    //如果直接解析失败,此方法将考虑TypeVariables和WildcardTypes的边界;但是,Object.class的边界将被忽略。

                    //因为事先检查过typeToMatch带泛型,
                    //应该是Xxx<T>类似这种类型,而resovle返回值就是Xxx.Class
                    Class<?> classToMatch = typeToMatch.resolve();
                    if (classToMatch != null && !classToMatch.isInstance(beanInstance)) {
                        //判断jdk动态代理对象,是不是Xxx.Class类型,不是直接返回false
                        return false;
                    }
                    
                    //根据BeanDefinition上的目标类型进行判断
                    //typeToMatch.isAssignableFrom:确定此ResolvableType是否可从指定的其他类型分配。
                    //即检查右侧类型targetType是否可以分配给左侧类型typeToMatch
                    //即判断targetType是不是typeToMatch,或者是typeToMatch的子类
                    if (typeToMatch.isAssignableFrom(targetType)) {
                        return true;
                    }
                }
                //mbd.targetType为null,说明是工厂方法的情况
                ResolvableType resolvableType = mbd.targetType;
                if (resolvableType == null) {
                	//获取工厂方法的返回值类型
                    resolvableType = mbd.factoryMethodReturnType;
                }
                //目标类匹配(带泛型的匹配)
                return (resolvableType != null && typeToMatch.isAssignableFrom(resolvableType));
            }
        }
        //单例池拿到了非null Bean,但是匹配能尝试的都尝试了,最终返回false
        return false;
    }
    else if (containsSingleton(beanName) && !containsBeanDefinition(beanName)) {
        // null instance registered
        // NullBean的情况,直接返回false
        return false;
    }

    // 走到这说明没有从单例池获取到实例
    
    // No singleton instance found -> check bean definition.
    // 检查一下当前容器有没有这个definition,没有就从父容器里判断
    BeanFactory parentBeanFactory = getParentBeanFactory();
    if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
        // No bean definition found in this factory -> delegate to parent.
        return parentBeanFactory.isTypeMatch(originalBeanName(name), typeToMatch);
    }

	//单例池中没有name对应的Bean对象,就只能根据BeanDefinition来判断出类型了
    
    // Retrieve corresponding bean definition.
    RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
    BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();

    // Set up the types that we want to match against
    // 设置要匹配的类型
    Class<?> classToMatch = typeToMatch.resolve();
    if (classToMatch == null) {
        classToMatch = FactoryBean.class;
    }
    
    //typesToMatch至少包含一个FactoryBean类型,为了处理FactoryBean引用的情况
    Class<?>[] typesToMatch = (FactoryBean.class == classToMatch ?
            new Class<?>[] {classToMatch} : new Class<?>[] {FactoryBean.class, classToMatch});


    // Attempt to predict the bean type
    // 尝试预测bean Class类型
    Class<?> predictedType = null;

    // We're looking for a regular reference but we're a factory bean that has
    // a decorated bean definition. The target bean should be the same type
    // as FactoryBean would ultimately return.
    //我们正在寻找常规引用,但我们是一个具有装饰bean定义的工厂bean。
    //目标bean应该与FactoryBean最终返回的类型相同
    if (!isFactoryDereference && dbd != null && isFactoryBean(beanName, mbd)) {
        // We should only attempt if the user explicitly set lazy-init to true
        // and we know the merged bean definition is for a factory bean.

        //非懒加载Bean、或允许FactoryBean初始化
        if (!mbd.isLazyInit() || allowFactoryBeanInit) {
            //获取被装饰的BeanDefinition(应该是工厂Bean背后真正类型的Bean定义吧??)
            RootBeanDefinition tbd = getMergedBeanDefinition(dbd.getBeanName(), dbd.getBeanDefinition(), mbd);
            //使用装饰的BeanDefinition推断类型
            //常规引用,希望拿到FactoryBean最终返回的类型
            //c. 推断bean Class类型,获取目标类型
            Class<?> targetType = predictBeanType(dbd.getBeanName(), tbd, typesToMatch);
            if (targetType != null && !FactoryBean.class.isAssignableFrom(targetType)) {
                //不为null,且不是FactoryBean,说明成功推断出FactoryBean最终返回的类型
                predictedType = targetType;
            }
        }
    }

    // If we couldn't use the target type, try regular prediction.
    // 如果我们不能使用(FactoryBean的?)目标类型,尝试常规预测。
    if (predictedType == null) {
        //c. 推断bean Class类型
        predictedType = predictBeanType(beanName, mbd, typesToMatch);
        if (predictedType == null) {
        	//推断失败,直接返回false
            return false;
        }
    }

    // Attempt to get the actual ResolvableType for the bean.
    // 尝试获取bean的实际ResolvableType。

	//predictedType是Class,不带泛型
    //这里希望推断出ResolvableType,它是带泛型的,更精确匹配
    ResolvableType beanType = null;

    // If it's a FactoryBean, we want to look at what it creates, not the factory class.
    // 如果它是FactoryBean,我们想看看它创建了什么,而不是工厂类。
    
    // predictedType类型如果是FactoryBean,得先实例化FactoryBean这个对象,然后调用getObjectType方法
    // 才能知道具体背后对应的类型
    if (FactoryBean.class.isAssignableFrom(predictedType)) {
        if (beanInstance == null && !isFactoryDereference) {
            //d. 先实例化FactoryBean对象,再获取FactoryBean创建的对象类型
            beanType = getTypeForFactoryBean(beanName, mbd, allowFactoryBeanInit);
            predictedType = beanType.resolve();
            if (predictedType == null) {
                return false;
            }
        }
    }
    //FactoryBean引用的情况
    else if (isFactoryDereference) {
        // Special case: A SmartInstantiationAwareBeanPostProcessor returned a non-FactoryBean
        // type but we nevertheless are being asked to dereference a FactoryBean...
        // Let's check the original bean class and proceed with it if it is a FactoryBean.
        // 特殊情况:SmartInstantationAwareBeanPostProcessor返回了一个非FactoryBean类型,但我们仍然被要求取消引用FactoryBean...
		// 让我们检查原始bean类,如果它是FactoryBean,则继续处理它。

		// 简单来说就是当前我们是工厂引用,但是推测类型拿到的类型不是FactoryBean类型(通过SmartInstantationAwareBeanPostProcessor返回的)
        // 所以我们拿原始BeanDefintion的类型,判断是不是FactoryBean,不是直接返回false
        // 是的话继续处理它
        
        //d. 推断bean Class类型是不是FactoryBean
        predictedType = predictBeanType(beanName, mbd, FactoryBean.class);
        if (predictedType == null || !FactoryBean.class.isAssignableFrom(predictedType)) {
            return false;
        }
    }

    // We don't have an exact type but if bean definition target type or the factory
    // method return type matches the predicted type then we can use that.
    // 我们没有确切的类型,但如果bean定义目标类型或工厂方法返回类型与预测类型匹配,那么我们可以使用它。
    if (beanType == null) {
        ResolvableType definedType = mbd.targetType;
        if (definedType == null) {
            definedType = mbd.factoryMethodReturnType;
        }
        //比较Class类型,一样,可以用带泛型的definedType替换
        if (definedType != null && definedType.resolve() == predictedType) {
            beanType = definedType;
        }
    }

    // If we have a bean type use it so that generics are considered
    // 如果我们有一个bean类型,请使用它,以便考虑泛型
    // (ResolvableType是带泛型的类型!!!!)
    if (beanType != null) {
        return typeToMatch.isAssignableFrom(beanType);
    }

    // If we don't have a bean type, fallback to the predicted type
    // 如果我们没有bean类型,回退到预测类型
    return typeToMatch.isAssignableFrom(predictedType);
}

比较复杂,大体流程分两步

  • 先从单例池获取实例,根据实例进行类型判断
  • 单例池没有则根据BeanDefinition进行类型判断

a. 获取FactoryBean创建的对象类型

org.springframework.beans.factory.support.FactoryBeanRegistrySupport#getTypeForFactoryBean

protected Class<?> getTypeForFactoryBean(FactoryBean<?> factoryBean) {
    try {
        if (System.getSecurityManager() != null) {...}
        else {
            //调用factoryBean.getObjectType()
            //获取FactoryBean创建的对象类型
            return factoryBean.getObjectType();
        }
    }
    catch (Throwable ex) {...}
}

为什么FactoryBean要单独设计一个getObjectType()方法?

  • 因为在判断一个Bean是否是某一个类型的时候,是不希望通过实例化后获取类型的,因为实例化了以后发现类型不匹配,也不会用,浪费。
  • 所以getObjectType方法的意义就是不用实例化FactoryBean的getObject对象,就能获取到对应的类型。

b. 泛型可能仅在目标类上匹配,而在代理上不匹配

jdk动态代理+泛型的时候,泛型可能仅在目标类上匹配,而在代理上不匹配,Demo:

public class Test2 {
	//具体接口
    public interface A {}
	//带泛型的接口
    public interface Generic<T> {}
	//具体实现类,指定了泛型具体类型
    public static class GenericA implements Generic<A> {}
	//Test2的成员变量,泛型接口+具体泛型类型
    private Generic<A> genericA;

    public static void main(String[] args) throws NoSuchFieldException {
        Field field = Test2.class.getDeclaredField("genericA");
        ResolvableType resolvableType = ResolvableType.forField(field);
        System.out.println(resolvableType.hasGenerics());//true
        //resolve返回的是具体Class类型,不带泛型
        System.out.println(resolvableType.resolve());//interface com.yth.Test2$Generic

        TargetSource targetSource = new TargetSource() {
            @Override
            public Class<?> getTargetClass() {
            	//模拟jdk动态代理,针对接口生成代理类
            	//接口上是没有具体泛型类型的
                return GenericA.class.getInterfaces()[0];
            }

            @Override
            public boolean isStatic() {
                return true;
            }

            @Override
            public Object getTarget() throws Exception {
                return new GenericA();
            }

            @Override
            public void releaseTarget(Object target) throws Exception {

            }
        };
        Object proxy = ProxyFactory.getProxy(targetSource);
        //proxy是jdk动态代理,面对接口生成的代理对象,接口上没有泛型具体类型
        //resolvableType.isInstance不仅判断类型,还会判断泛型,所以是false
        System.out.println(resolvableType.isInstance(proxy));//false

		//GenericA是具体类,在实现类上指定了泛型具体类型了,所以是true
        System.out.println(resolvableType.isInstance(new GenericA()));//true
        
        //resolve返回的是Class类型:interface com.yth.Test2$Generic
        System.out.println(resolvableType.resolve().isInstance(new GenericA()));//true
        System.out.println(resolvableType.resolve().isInstance(proxy));//true
    }
}

ResolvableType是带泛型的类型,resolvableType.resolve()返回的是Class类型

c. 推断bean Class类型

真正实现类是org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#predictBeanType

protected Class<?> predictBeanType(String beanName, RootBeanDefinition mbd, Class<?>... typesToMatch) {
    //推测目标类型
    Class<?> targetType = determineTargetType(beanName, mbd, typesToMatch);
    
    // Apply SmartInstantiationAwareBeanPostProcessors to predict the
    // eventual type after a before-instantiation shortcut.
    // 在实例化前快捷方式之后应用SmartInstantationAwareBeanPostProcessors预测最终类型。
    if (targetType != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
        boolean matchingOnlyFactoryBean = typesToMatch.length == 1 && typesToMatch[0] == FactoryBean.class;
        for (SmartInstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().smartInstantiationAware) {
            Class<?> predicted = bp.predictBeanType(targetType, beanName);
            //推测出来如果不为null,则
            //不是只匹配FactoryBean则直接返回
            //推测出来的是FactoryBean也直接返回
            if (predicted != null &&
                    (!matchingOnlyFactoryBean || FactoryBean.class.isAssignableFrom(predicted))) {
                return predicted;
            }
        }
    }
    return targetType;
}

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#determineTargetType

//确定给定bean定义的目标类型,class类型
protected Class<?> determineTargetType(String beanName, RootBeanDefinition mbd, Class<?>... typesToMatch) {
    Class<?> targetType = mbd.getTargetType();
    if (targetType == null) {
        targetType = (mbd.getFactoryMethodName() != null ?
        		//1.确定基于工厂方法的给定bean定义的目标Class类型
                getTypeForFactoryMethod(beanName, mbd, typesToMatch) :
                //2.解析指定bean定义的bean类,将bean类名解析为class引用(如果需要),并将解析的class存储在bean定义中以供进一步使用。
                resolveBeanClass(mbd, beanName, typesToMatch));
        if (ObjectUtils.isEmpty(typesToMatch) || getTempClassLoader() == null) {
            mbd.resolvedTargetType = targetType;
        }
    }
    return targetType;
}

看下普通Bean情况
org.springframework.beans.factory.support.AbstractBeanFactory#resolveBeanClass

protected Class<?> resolveBeanClass(RootBeanDefinition mbd, String beanName, Class<?>... typesToMatch)
        throws CannotLoadBeanClassException {

    try {
        //beanClass已经加载了直接返回
        if (mbd.hasBeanClass()) {
            return mbd.getBeanClass();
        }
        if (System.getSecurityManager() != null) {...}
        else {
            //还没有被加载,则加载
            return doResolveBeanClass(mbd, typesToMatch);
        }
    }
    catch (PrivilegedActionException pae) {...}
    catch (ClassNotFoundException ex) {...}
    catch (LinkageError err) {...}
}
private Class<?> doResolveBeanClass(RootBeanDefinition mbd, Class<?>... typesToMatch)
        throws ClassNotFoundException {

    ClassLoader beanClassLoader = getBeanClassLoader();
    ClassLoader dynamicLoader = beanClassLoader;
    boolean freshResolve = false;

    if (!ObjectUtils.isEmpty(typesToMatch)) {
        // When just doing type checks (i.e. not creating an actual instance yet),
        // use the specified temporary class loader (e.g. in a weaving scenario).
        // 当只进行类型检查(即尚未创建实际实例)时,请使用指定的临时类加载器(例如在编织场景中)。
        ClassLoader tempClassLoader = getTempClassLoader();
        if (tempClassLoader != null) {
            dynamicLoader = tempClassLoader;
            freshResolve = true;
            //用于装饰ClassLoader的基类,如OverridingClassLoador和ShadowingClassLoader
            //提供对排除的包和类的通用处理。
            if (tempClassLoader instanceof DecoratingClassLoader) {
                DecoratingClassLoader dcl = (DecoratingClassLoader) tempClassLoader;
                for (Class<?> typeToMatch : typesToMatch) {
                	//添加要从装饰中排除的类名(例如重写)。
                    //在这里注册的任何类名都将由父ClassLoader以通常的方式处理。

                    //推测:excludeClass中的class由父类加载器加载,
                    //其他的类用当前临时类加载器加载
                    dcl.excludeClass(typeToMatch.getName());
                }
            }
        }
    }

    String className = mbd.getBeanClassName();
    if (className != null) {
    	//评估bean定义中包含的给定String,可能将其解析为表达式。
        //className可能是个Spring表达式
        Object evaluated = evaluateBeanDefinitionString(className, mbd);
        if (!className.equals(evaluated)) {
        	//不一样,说明解析成功了,返回值可能直接就是Class,或新的字符串内容
        	
            // A dynamically resolved expression, supported as of 4.2...
            // 动态解析表达式
            if (evaluated instanceof Class) {
                return (Class<?>) evaluated;
            }
            else if (evaluated instanceof String) {
                className = (String) evaluated;
                freshResolve = true;
            }
            else {...}
        }
        if (freshResolve) {
            // When resolving against a temporary class loader, exit early in order
            // to avoid storing the resolved Class in the bean definition.
            // 当针对临时类加载器进行解析时,请提前退出,以避免将解析的类存储在bean定义中。
            if (dynamicLoader != null) {
                try {
                	//这里加载直接返回,不会保存到BeanDefinition中
                    return dynamicLoader.loadClass(className);
                }
                catch (ClassNotFoundException ex) {...}
            }
            return ClassUtils.forName(className, dynamicLoader);
        }
    }

    // Resolve regularly, caching the result in the BeanDefinition...
    // 常规解析,在BeanDefinition中缓存结果…
    return mbd.resolveBeanClass(beanClassLoader);
}

org.springframework.beans.factory.support.AbstractBeanDefinition#resolveBeanClass

public Class<?> resolveBeanClass(@Nullable ClassLoader classLoader) throws ClassNotFoundException {
    String className = getBeanClassName();
    if (className == null) {
        return null;
    }
    //解析
    Class<?> resolvedClass = ClassUtils.forName(className, classLoader);
    //缓存到Bean定义中
    this.beanClass = resolvedClass;
    return resolvedClass;
}

org.springframework.util.ClassUtils#forName

//替换Class.forName(),它还返回原语(例如“int”)和数组类名(例如“String[]”)的类实例。
//此外,它还能够解析Java源代码样式中的嵌套类名(例如“Java.lang.Thread.State”而不是“Java.llang.Thread$State”)。
public static Class<?> forName(String name, @Nullable ClassLoader classLoader)
        throws ClassNotFoundException, LinkageError {

    Assert.notNull(name, "Name must not be null");

	//如果合适,根据JVM的原语类命名规则,将给定的类名解析为原语类。
    //还支持基本数组的JVM内部类名。不支持基元数组的“[]”后缀符号;这仅由forName(String,ClassLoader)支持。
    Class<?> clazz = resolvePrimitiveClassName(name);
    if (clazz == null) {
        clazz = commonClassCache.get(name);
    }
    if (clazz != null) {
        return clazz;
    }

    // "java.lang.String[]" style arrays
    if (name.endsWith(ARRAY_SUFFIX)) {
        String elementClassName = name.substring(0, name.length() - ARRAY_SUFFIX.length());
        Class<?> elementClass = forName(elementClassName, classLoader);
        return Array.newInstance(elementClass, 0).getClass();
    }

    // "[Ljava.lang.String;" style arrays
    if (name.startsWith(NON_PRIMITIVE_ARRAY_PREFIX) && name.endsWith(";")) {
        String elementName = name.substring(NON_PRIMITIVE_ARRAY_PREFIX.length(), name.length() - 1);
        Class<?> elementClass = forName(elementName, classLoader);
        return Array.newInstance(elementClass, 0).getClass();
    }

    // "[[I" or "[[Ljava.lang.String;" style arrays
    if (name.startsWith(INTERNAL_ARRAY_PREFIX)) {
        String elementName = name.substring(INTERNAL_ARRAY_PREFIX.length());
        Class<?> elementClass = forName(elementName, classLoader);
        return Array.newInstance(elementClass, 0).getClass();
    }

    ClassLoader clToUse = classLoader;
    if (clToUse == null) {
        clToUse = getDefaultClassLoader();
    }
    try {
    	//核心
        return Class.forName(name, false, clToUse);
    }
    catch (ClassNotFoundException ex) {...}
}

d. 先实例化FactoryBean对象,再获取FactoryBean创建的对象类型

org.springframework.beans.factory.support.AbstractBeanFactory#getTypeForFactoryBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, boolean)

protected ResolvableType getTypeForFactoryBean(String beanName, RootBeanDefinition mbd, boolean allowInit) {
    //先尝试从BeanDefinition的attribute里获取目标类型
    ResolvableType result = getTypeForFactoryBeanFromAttributes(mbd);
    if (result != ResolvableType.NONE) {
        return result;
    }
	//允许初始化,并且是单例,则实例化FactoryBean后,再获取目标类型
    if (allowInit && mbd.isSingleton()) {
        try {
        	//FactoryBean引用,获取FactoryBean自身实例对象
            FactoryBean<?> factoryBean = doGetBean(FACTORY_BEAN_PREFIX + beanName, FactoryBean.class, null, true);
            //a.获取FactoryBean创建的对象类型
            Class<?> objectType = getTypeForFactoryBean(factoryBean);
            return (objectType != null ? ResolvableType.forClass(objectType) : ResolvableType.NONE);
        }
        catch (BeanCreationException ex) {...}
    }
    return ResolvableType.NONE;
}

2. resolvableDependencies

在这里插入图片描述

Spring启动的时候会往这个map赋值
org.springframework.context.support.AbstractApplicationContext#prepareBeanFactory
在这里插入图片描述

注入过程中如果这个map中已经存在对应类型key,直接取value进行注入。

自己也可以定义:
在这里插入图片描述

3. 判断是不是自己注入自己

org.springframework.beans.factory.support.DefaultListableBeanFactory#isSelfReference

//确定给定的beanName/ccandidateName对是否指示自引用,
//即候选是否指向原始bean或原始bean上的工厂方法。
private boolean isSelfReference(@Nullable String beanName, @Nullable String candidateName) {
    return (beanName != null && candidateName != null &&
            (beanName.equals(candidateName) || (containsBeanDefinition(candidateName) &&
                    beanName.equals(getMergedLocalBeanDefinition(candidateName).getFactoryBeanName()))));
}

注入的时候优先考虑别人

4. 判断能不能注入

虽然name对应的类型和要注入的类型是一样的,但是也不一定能注入,比如:
在这里插入图片描述

org.springframework.beans.factory.support.DefaultListableBeanFactory#isAutowireCandidate(java.lang.String, org.springframework.beans.factory.config.DependencyDescriptor)

public boolean isAutowireCandidate(String beanName, DependencyDescriptor descriptor)
        throws NoSuchBeanDefinitionException {

    return isAutowireCandidate(beanName, descriptor, getAutowireCandidateResolver());
}

protected boolean isAutowireCandidate(
        String beanName, DependencyDescriptor descriptor, AutowireCandidateResolver resolver)
        throws NoSuchBeanDefinitionException {
    //根据BeanDefinition判断beanName对应的Bean可不可以用来进行依赖注入

	//获取Bean规范名称
    String bdName = BeanFactoryUtils.transformedBeanName(beanName);
    if (containsBeanDefinition(bdName)) {
        //核心方法
        return isAutowireCandidate(beanName, getMergedLocalBeanDefinition(bdName), descriptor, resolver);
    }
    //判断单例池中有没有这个Bean实例(存在有实例,没有BeanDefinition的情况)
    else if (containsSingleton(beanName)) {
        //核心方法
        return isAutowireCandidate(beanName, new RootBeanDefinition(getType(beanName)), descriptor, resolver);
    }

    //当前工厂,没有这个BeanDefinition,单例池也没有Bean
    //则从父工厂判断能否注入
    BeanFactory parent = getParentBeanFactory();
    if (parent instanceof DefaultListableBeanFactory) {...}
    else if (parent instanceof ConfigurableListableBeanFactory) {...}
    else {...}
}

protected boolean isAutowireCandidate(String beanName, RootBeanDefinition mbd,
        DependencyDescriptor descriptor, AutowireCandidateResolver resolver) {

    String bdName = BeanFactoryUtils.transformedBeanName(beanName);
    //解析指定bean定义的bean类,将bean类名解析为class引用(如果需要),
    //并将解析的class存储在bean定义中以供进一步使用。
    resolveBeanClass(mbd, bdName);
    
    //和@Bean有关系,工厂方法
    if (mbd.isFactoryMethodUnique && mbd.factoryMethodToIntrospect == null) {
        //给factoryMethodToIntrospect赋值,记录@Bean对应的Method对象
        //解析指定bean定义中的工厂方法,RootBeanDefinition.getResolvedFactoryMethod()可以检查结果。
        new ConstructorResolver(this).resolveFactoryMethodIfPossible(mbd);
    }
    BeanDefinitionHolder holder = (beanName.equals(bdName) ?
            this.mergedBeanDefinitionHolders.computeIfAbsent(beanName,
                    key -> new BeanDefinitionHolder(mbd, beanName, getAliases(bdName))) :
            new BeanDefinitionHolder(mbd, beanName, getAliases(bdName)));
    //核心这
    return resolver.isAutowireCandidate(holder, descriptor);
}

resolver真正的类是QualifierAnnotationAutowireCandidateResolver

org.springframework.beans.factory.annotation.QualifierAnnotationAutowireCandidateResolver#isAutowireCandidate

public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
    //先执行上层父类的判断,如果匹配成功,在由自己匹配
    boolean match = super.isAutowireCandidate(bdHolder, descriptor);
    if (match) {
    	//参数级别注解校验
        //descriptor.getAnnotations()拿的是属性 或 方法参数 前的注解,拿不到方法上的注解
        match = checkQualifiers(bdHolder, descriptor.getAnnotations());
        if (match) {
            MethodParameter methodParam = descriptor.getMethodParameter();
            if (methodParam != null) {
            	//方法级别注解校验
                Method method = methodParam.getMethod();
                if (method == null || void.class == method.getReturnType()) {
                    //methodParam.getMethodAnnotations()拿到的是方法上的注解
                    match = checkQualifiers(bdHolder, methodParam.getMethodAnnotations());
                }
            }
        }
    }
    return match;
}

QualifierAnnotationAutowireCandidateResolver主要处理@Qualifier注解

QualifierAnnotationAutowireCandidateResolver的父类是GenericTypeAwareAutowireCandidateResolver:处理泛型相关的数据,判断能否注入

GenericTypeAwareAutowireCandidateResolver的父类是SimpleAutowireCandidateResolver:判断BeanDefinition的autowireCandiate属性是否为true

责任链模式。

接下来简单介绍一下,非源码级别,应用级别。

SimpleAutowireCandidateResolver

在这里插入图片描述

GenericTypeAwareAutowireCandidateResolver

org.springframework.beans.factory.support.GenericTypeAwareAutowireCandidateResolver#isAutowireCandidate

public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
    //super就是SimpleAutowireCandidateResolver,判断BeanDefinition的autowireCandiate属性是否为true
    if (!super.isAutowireCandidate(bdHolder, descriptor)) {
        // If explicitly false, do not proceed with any other checks...
        return false;
    }
    //父类通过,在判断当前类的逻辑,处理泛型相关逻辑
    return checkGenericTypeMatch(bdHolder, descriptor);
}

源码就不看了,直接演示一下获取泛型类型的核心API:

public class GenericTest {
    @Component
    public static class OrderService {}

    @Component
    public static class StockService {}

    public static class BaseService<O, S> {
        @Autowired
        protected O o;
        @Autowired
        protected S s;
    }

    @Component
    public static class UserService extends BaseService<OrderService, StockService> {
        public void test() {
            System.out.println(o);
            System.out.println(s);
        }
    }

    public static void main(String[] args) {
        // 演示一下获取泛型类型的核心API
        UserService userService = new UserService();

        Class<?> superclass = userService.getClass().getSuperclass();
        // 获取类上定义的泛型变量
        for (TypeVariable<? extends Class<?>> typeParameter : superclass.getTypeParameters()) {
            System.out.println(typeParameter.getName());
        }

        // 获取类中成员变量的泛型类型
        for (Field declaredField : superclass.getDeclaredFields()) {
            System.out.println(declaredField.getGenericType());
        }

        Type genericSuperclass = userService.getClass().getGenericSuperclass();
        // 判断是否是泛型类型
        if (genericSuperclass instanceof ParameterizedType) {
            System.out.println("是泛型类型");
            ParameterizedType parameterizedType = (ParameterizedType)genericSuperclass;
            // 获取泛型
            for (Type actualTypeArgument : parameterizedType.getActualTypeArguments()) {
                System.out.println("泛型类型:" + actualTypeArgument);
            }
        }

    }
}
public class TypeTest<T> {

    private int i;
    private Integer it;
    private int[] iarray;
    private List list;
    private List<String> slist;
    private List<T> tlist;
    private T t;
    private T[] tarray;

    public static void main(String[] args) throws NoSuchFieldException {

        test(TypeTest.class.getDeclaredField("i"));
        System.out.println("=======");
        test(TypeTest.class.getDeclaredField("it"));
        System.out.println("=======");
        test(TypeTest.class.getDeclaredField("iarray"));
        System.out.println("=======");
        test(TypeTest.class.getDeclaredField("list"));
        System.out.println("=======");
        test(TypeTest.class.getDeclaredField("slist"));
        System.out.println("=======");
        test(TypeTest.class.getDeclaredField("tlist"));
        System.out.println("=======");
        test(TypeTest.class.getDeclaredField("t"));
        System.out.println("=======");
        test(TypeTest.class.getDeclaredField("tarray"));

    }

    public static void test(Field field) {

        if (field.getType().isPrimitive()) {
            System.out.println(field.getName() + "是基本数据类型");
        } else {
            System.out.println(field.getName() + "不是基本数据类型");
        }

        if (field.getGenericType() instanceof ParameterizedType) {
            System.out.println(field.getName() + "是泛型类型");
        } else {
            System.out.println(field.getName() + "不是泛型类型");
        }

        if (field.getType().isArray()) {
            System.out.println(field.getName() + "是普通数组");
        } else {
            System.out.println(field.getName() + "不是普通数组");
        }

        if (field.getGenericType() instanceof GenericArrayType) {
            System.out.println(field.getName() + "是泛型数组");
        } else {
            System.out.println(field.getName() + "不是泛型数组");
        }

        if (field.getGenericType() instanceof TypeVariable) {
            System.out.println(field.getName() + "是泛型变量");
        } else {
            System.out.println(field.getName() + "不是泛型变量");
        }

    }
}

QualifierAnnotationAutowireCandidateResolver

org.springframework.beans.factory.annotation.QualifierAnnotationAutowireCandidateResolver#isAutowireCandidate

public boolean isAutowireCandidate(BeanDefinitionHolder bdHolder, DependencyDescriptor descriptor) {
    //先执行上层判断,上层是GenericTypeAwareAutowireCandidateResolver,泛型的判断
    boolean match = super.isAutowireCandidate(bdHolder, descriptor);
    if (match) {
        //先拿到参数级别@Qualifier注解进行校验
        //descriptor.getAnnotations()拿的是参数级别的注解
        match = checkQualifiers(bdHolder, descriptor.getAnnotations());
        if (match) {
            MethodParameter methodParam = descriptor.getMethodParameter();
            if (methodParam != null) {
            	//再拿方法级别的@Qualifier注解进行校验
                Method method = methodParam.getMethod();
                if (method == null || void.class == method.getReturnType()) {
                    //methodParam.getMethodAnnotations()拿到的是方法上的注解
                    match = checkQualifiers(bdHolder, methodParam.getMethodAnnotations());
                }
            }
        }
    }
    return match;
}

当前注入点上有Qualifier注解的话,会判断候选Bean中是否也写了Qualifier注解,然后进行值匹配,checkQualifiers就不看了,介绍一下应用场景:

定义两个注解:

@Target({ElementType.TYPE, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier("random")//@Random上标注了@Qualifier
public @interface Random {
}
@Target({ElementType.TYPE, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier("roundRobin")//@RoundRobin上标注了@Qualifier
public @interface RoundRobin {
}

定义一个接口和两个实现类,表示负载均衡:

public interface LoadBalance {
	String select();
}
@Component
@Random
public class RandomStrategy implements LoadBalance {

	@Override
	public String select() {
		return null;
	}
}
@Component
@RoundRobin
public class RoundRobinStrategy implements LoadBalance {

	@Override
	public String select() {
		return null;
	}
}

使用:

@Component
public class UserService  {

	@Autowired
	@RoundRobin//使用注解就能切换实现
	private LoadBalance loadBalance;

	public void test() {
		System.out.println(loadBalance);
	}

}

5. 添加到结果集

org.springframework.beans.factory.support.DefaultListableBeanFactory#addCandidateEntry

//向候选映射添加一个条目:如果可用,则添加一个bean实例,或者仅添加已解析的类型,
//从而防止在主候选选择之前提前进行bean初始化。
private void addCandidateEntry(Map<String, Object> candidates, String candidateName,
        DependencyDescriptor descriptor, Class<?> requiredType) {
	//具有嵌套元素的多元素声明的依赖描述符。
    if (descriptor instanceof MultiElementDescriptor) {
        //结果集放入的是Bean实例
        Object beanInstance = descriptor.resolveCandidate(candidateName, requiredType, this);
        if (!(beanInstance instanceof NullBean)) {
            candidates.put(candidateName, beanInstance);
        }
    }
    else if (containsSingleton(candidateName) || (descriptor instanceof StreamDependencyDescriptor &&
            ((StreamDependencyDescriptor) descriptor).isOrdered())) {
        //如果单例池中存在
        //或者是StreamDependencyDescriptor:用于流访问多个元素的依赖描述符标记。
        //直接放入Bean对象
        Object beanInstance = descriptor.resolveCandidate(candidateName, requiredType, this);
        candidates.put(candidateName, (beanInstance instanceof NullBean ? null : beanInstance));
    }
    else {
        //将匹配到beanName以及beanClass存入
        candidates.put(candidateName, getType(candidateName));
    }
}

放入Bean对象的情况:
org.springframework.beans.factory.config.DependencyDescriptor#resolveCandidate

public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory)
        throws BeansException {

    return beanFactory.getBean(beanName);
}

放入Bean Class的情况:
org.springframework.beans.factory.support.AbstractBeanFactory#getType(java.lang.String)

public Class<?> getType(String name) throws NoSuchBeanDefinitionException {
    return getType(name, true);
}

public Class<?> getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException {
    String beanName = transformedBeanName(name);

    // Check manually registered singletons.
    // 检查手动注册的单例

	//如果有实例,根据实例获取Class类型
    Object beanInstance = getSingleton(beanName, false);
    if (beanInstance != null && beanInstance.getClass() != NullBean.class) {
    	//FactoryBean,常规引用的情况
        if (beanInstance instanceof FactoryBean && !BeanFactoryUtils.isFactoryDereference(name)) {
            return getTypeForFactoryBean((FactoryBean<?>) beanInstance);
        }
        else {
        	//普通Bean、FactoryBean引用的情况...
            return beanInstance.getClass();
        }
    }
	
	//检查BeanDefinition,当前工厂不存在,委托父类工厂处理
	
    // No singleton instance found -> check bean definition.
    BeanFactory parentBeanFactory = getParentBeanFactory();
    if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
        // No bean definition found in this factory -> delegate to parent.
        return parentBeanFactory.getType(originalBeanName(name));
    }
	
	//根据BeanDefinition获取Class类型
	
    RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);

    // Check decorated bean definition, if any: We assume it'll be easier
    // to determine the decorated bean's type than the proxy's type.
    // 检查修饰的bean定义(如果有):我们假设确定修饰的beam的类型比确定代理的类型更容易。
    BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
    if (dbd != null && !BeanFactoryUtils.isFactoryDereference(name)) {
        RootBeanDefinition tbd = getMergedBeanDefinition(dbd.getBeanName(), dbd.getBeanDefinition(), mbd);
        Class<?> targetClass = predictBeanType(dbd.getBeanName(), tbd);
        if (targetClass != null && !FactoryBean.class.isAssignableFrom(targetClass)) {
            return targetClass;
        }
    }

	//推测Bean Class类型,见1.2.c
    Class<?> beanClass = predictBeanType(beanName, mbd);
	
	// 处理FactoryBean情况
    // Check bean class whether we're dealing with a FactoryBean.
    if (beanClass != null && FactoryBean.class.isAssignableFrom(beanClass)) {
        if (!BeanFactoryUtils.isFactoryDereference(name)) {
            // If it's a FactoryBean, we want to look at what it creates, not at the factory class.
            return getTypeForFactoryBean(beanName, mbd, allowFactoryBeanInit).resolve();
        }
        else {
            return beanClass;
        }
    }
    //普通Bean情况
    else {
        return (!BeanFactoryUtils.isFactoryDereference(name) ? beanClass : null);
    }
}

6. 回退匹配

搜了一下调用点,在GenericTypeAwareAutowireCandidateResolver中,泛型处理的时候:
在这里插入图片描述

回退匹配允许不可解析的泛型,例如纯HashMap-to-Map<String,String>;
实际上也可以将java.util.Properties映射到任何Map(因为尽管形式上是Map<Object,Object>,java.util.Properties通常被视为Map<String,String>)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Spring源码分析(十一)依赖注入源码解析4:DefaultListableBeanFactory#findAutowireCandidates 根据类型查找所有候选Bean 的相关文章

随机推荐