账号密码登录
微信安全登录
微信扫描二维码登录

登录后绑定QQ、微信即可实现信息互通

手机验证码登录
找回密码返回
邮箱找回 手机找回
注册账号返回
其他登录方式
分享
  • 收藏
    X
    Spring源码问题:findAutowireCandidates这个if的意义是什么?
    11
    0
    这些天研究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:@Componentpublic 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))不就可以了?请明白的赐教!
    0
    打赏
    收藏
    点击回答
        全部回答
    • 0
    更多回答
    扫一扫访问手机版

    回答动态

    酒后略带风情:发布了悬赏问题Android内存中Graphics与Code占用过高预计能赚取 10积分收益
    扛起拖把扫天下:发布了悬赏问题typescript如何导出接口配置?求解,谢谢!预计能赚取 10积分收益
    发布了悬赏问题Vue 如何改变返回页面的路径?如让B页面只能返回到A页面.预计能赚取 11积分收益
    发布了悬赏问题vue H5移动端;底部bottom固定定位,安卓弹起键盘导致页面变形如何解决?预计能赚取 10积分收益
    发布了悬赏问题请问为什么tomcat8.5 GET请求中文正常,POST请求还需要设置UTF-8.预计能赚取 10积分收益
    发布了悬赏问题vue2.5+ts创建以及引入jq的方法预计能赚取 11积分收益
    情场浪女:发布了悬赏问题import ggplot时报错module 'pandas' has no attribute 'tslib'预计能赚取 10积分收益
    见心书画许老师18753375161:发布了悬赏问题echarts3 legend禁止点击事件,允许悬浮事件预计能赚取 11积分收益
    aa_92cb0bd09f:发布了悬赏问题codewar上的一个问题预计能赚取 11积分收益
    低谷有雾:发布了悬赏问题定时执行爬虫任务,通过循环监视,但是没有成功,求解答预计能赚取 11积分收益