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
以下为部门核心源码截图: