转载自:http://www.tuicool.com/articles/myqUvay
我们都知道, spring 提供了Resource、Autowired这两个注解用于注入,另外在xml配置文件中,beans标签下有一个参数default-autowire用来设置默认的注入类型。
这里我先说明一下default-autowire的用途。
首先default-autowire参数有几个可选值:
default:实际上是会优先执行constructor然后是byType
byType:这个是会根据类型去注入,当找到了会直接注入,没有找到不会报错,但是找到多个会报No unique bean of type的错误
byName:这个会根据name注入
constructor:这个是通过构造注入
no:不启用自动注入
下面说一下@Autowired是怎么 工作 的,网上很多人都说这个是通过byType注入的,实际上并不完全正确,实际上他是这样处理的:
1、根据类型找到所有满足条件的bean
2、判断bean长度,如果没有,则根据@Autowired中的required属性进行判断是否抛出异常(默认为true)
3、如果多于一个,则尝试寻找最优的那一个(根据名字来查找),如果最优的未找到,则抛出异常
4、如果只有一个,则直接使用此bean
所以说这个注解实际上会去寻找最优的一个Bean。另外这里注入也有个问题,就是注解放在属性上,则通过的是属性名去注入的,这个没什么说的;但是如果放在setter上,则是通过参数选择的注入,比如setA(A b),实际上他会注入到你上面声明的b变量上,而不是a。
最后我们来了解下@Resource是怎么工作的。
网上都说这个是根据的byName去注入的,其实也不对,实际上他是下面这样的:
1、获取名称,判断容器中是否存在此name的bean
2、如果存在,则直接使用此name进行查询
3、否则退化到默认的autowire查找方式
而@Resource其实没有@Autowired那么怪异,属性上用的名称就是属性民,而setter方法上也是方法名确定的。比如setA(A b)注入的就是a属性。
在我们现在项目中用的方式是采用default-autowire=”byName”,而标注的是使用@Autowired根据类型注入的。原因实际上是因为我们项目有一点特殊处理,具体可以参考 《Spring中默认bean名称的生成策略/方式修改》 这篇文章