Spring中使用@Autowired注入属性的奥秘

写这个博客的时候,我首先引入一个Java基础面试题。Autowired注解与Resource注解的区别?

 

假如你回答:

@Autowired是默认根据类型注入,如果需要根据字段名注入,则需要加上@Qualifier(name="xxx");@Resource默认根据字段名注入,如果字段名没找到bean就根据类型注入。

那么我接着问一个问题:

@Autowired如果不加@Qualifier注解,会根据字段名注入吗?

example:我有一个MyService接口,两个它的实现类MyServiceImpl2和MyServiceImpl3,分别指定serviceName为myService2和myService3,然后我在Test类中注入这两个实例。如下:

@Component
public class Test {
    @Autowired
    private MyService myService2;
    @Autowired
    private MyService myService3;
    
    public void run(){
        // do something
    }
}

大家觉得上面的两个service能注入成功吗?项目运行正常吗?

 

首先我先公布一下答案,这个是肯定能注入成功的。为什么呢?

因为Spring中对@Autowired注入的字段,首先根据类型去容器中找出所有匹配的Bean,如果只有一个就直接注入即可,如果有多个则取出来放到一个Map中(key为beanName,value为具体的bean),然后去查找Map中有@Primary的bean进行返回;如果没有,再去找Map中优先级最大的Bean进行返回;如果也没有,则根据字段名去Map中匹配key进行返回。

解析依赖注入的bean方法:

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

从多个bean中确定注入的bean方法:

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

以下为部门核心源码截图:

 

 

posted @ 2021-01-12 17:06  今夕是何年?  阅读(843)  评论(0编辑  收藏  举报