Spring问题:findAutowireCandidates这个if的意义是什么?

这些天研究Spring源码,遇到一个问题始终想不明白,resolveDependency->doResolveDependency->findAutowireCandidates中有这样一段代码:

Map<String, Object> result = new LinkedHashMap<>(candidateNames.length);
    for (Map.Entry<Class<?>, Object> classObjectEntry : this.resolvableDependencies.entrySet()) {
            Class<?> autowiringType = classObjectEntry.getKey();
            // autowiringType是requiredType的父类或本身
            if (autowiringType.isAssignableFrom(requiredType)) {
                Object autowiringValue = classObjectEntry.getValue();
                autowiringValue = AutowireUtils.resolveAutowiringValue(autowiringValue, requiredType);
                if (requiredType.isInstance(autowiringValue)) {
                    result.put(ObjectUtils.identityToString(autowiringValue), autowiringValue);
                    break;
                }
            }
        }

请问这个if (autowiringType.isAssignableFrom(requiredType))的意义是什么?
为此我做了个试验:
首先创建A、A1、A2,A1继承A,A2继承A1,其中没有任何代码。
然后创建User类,只有一个成员变量A1 a1:

public class User {

    @Autowired
    private A1 a1;

    public A1 getA1() {
        return a1;
    }

    public void setA1(A1 a1) {
        this.a1 = a1;
    }
}

findAutowireCandidates.xml:

    <bean class="A1" name="a1"/>
    <bean class="A2" name="a2"/>
    <bean class="findAutowireCandidates.User" name="user" autowire="byType"/>
    <context:component-scan base-package="findAutowireCandidates"/>

这种情况下一定会报异常,因为User类a1在自动注入的时候会有多个bean与之匹配,为了避免这种情况产生可以使用@Primary等方法,但那些不是要讨论的主题,这里用另一个方法,自定义一个BeanFactoryPostProcessor,向resolvableDependencies中注册一个A2:

@Component
public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
        configurableListableBeanFactory.registerResolvableDependency(A2.class,new A2());
    }
}

最后写个main方法:

public class TestFindAutowireCandidates {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("findAutowireCandidates.xml");
    }
}

最后运行,会发现依然报错,原因依然是User的a1有多个bean与之匹配:a1、a2,接着对MyBeanFactoryPostProcessor做如下修改:

configurableListableBeanFactory.registerResolvableDependency(A.class,new A2());

把key改成A.class,再运行就不会报错了,而且User的a1注入的不是a1、a2,而是MyBeanFactoryPostProcessor中这个new出来的A2对象。

以上实验纠其原因,就是开头提到的这个if (autowiringType.isAssignableFrom(requiredType)),这个if的意思是如果autowiringType是requiredType的本身或其父类,才可以进来。

findAutowireCandidates这个方法的大概意思就是要找到与requiredType类型匹配的所有候选bean,先在resolvableDependencies中查找,再从容器中所有bean中查找。后者我没什么问题,主要是前者,为什么在resolvableDependencies中查找时,如果autowiringType是requiredType的子类会被筛选掉呢?也就是前面试验中第一种报错的情况:如果我在resolvableDependencies中注册A2.class,new A2()这个键值对,由于A2是A1的子类,这里就会被筛选掉,导致这个MyBeanFactoryPostProcessor写了跟没写一样;但如果你注册的是A.class,new A2()就会生效。

但是为啥会这么写呢?如果没有这个if (autowiringType.isAssignableFrom(requiredType))不是也OK么?直接判断if (requiredType.isInstance(autowiringValue))不就可以了?请明白的赐教!

mark 一会儿来看大佬解析

还不是Class.isAssignableFrom这个方法,它是A.class.isAssignableFrom(B.class),它是判断B是不是A的实现类或者子类,当你注册key为A2的时候,bean的属性为A1,此时A2.class.isAssignableFrom(A1)当然是false,你注册的key为A是,A.class.isAssignableFrom(A1),这就true,就走进去了