直接用表格表说明比较直观:
@Autowired | @Resource | |
相同点 | 1.使用注解的方法注入bean。 2.注解的位置可以是容器类中的属性,也可以是其中的setter方法: 或者是 | |
不同点 | (1)默认按类型注入; (2)依赖对象必须存在,如果要允许null值,可以设置它的required属性为false @Autowired(required=false); (3)如果要使用名称装配,配合@Qualifier注解, @Autowired @Qualifier(value="predicteDao")
| (1)默认按名称进行注入,通过name属性进行指定对应bean的Id或者name; @Resource(name="predicteDao") (2)实践证明,不使用name也可,比如 @Resource 默认会按类型注入,和 @Autowired效果一样。
|
注入顺序 | 1、spring先找类型为***的bean 2、如果存在且唯一,则OK 3、如果不唯一,寻找name为***的bean。因为bean的name有唯一性,所以,到这里应该能确定是否存在满足要求的bean了 | 1. 如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常 2. 如果指定了name,则从上下文中查找名称(id或name)匹配的bean进行装配,找不到则抛出异常 3. 如果指定了type,则从上下文中找到类型匹配的唯一bean进行装配,找不到或者找到多个,都会抛出异常 4. 如果既没有指定name,又没有指定type,则自动按照byName方式进行装配;如果没有匹配,则回退为一个原始类型进行匹配,如果匹配则自动装配。 |
总结一下 | 1.@Autowired 属于Spring的注解,@Resource属于JDK的注解 2.如果一个接口有多个实现类的情况,建议使用@Resource,可以根据其bean的名称进行注入,当然也可以使用@Autowired配合@Qualifier注解 3.个人喜欢@Autowired,并且使用其默认参数(即不设置equired=false),对于bean为null的情况,tomcat之类的中间件启动时将会提前报错,便于尽早处理 |
深入一点
注:以下内容由作者亲自实验,实验环境为(Win10+JDK1.7.40+Spring4.1.5.RELEASE)
1、1个接口,2个实现类,使用@Resource注解,如下
这2个bean实现的是同一个接口。
(1)那么我们使用如下2种方式注解时,注入的是id="paymentService22",name="paymentService2"的bean;也就是说,使用id或者name属性都能成功注入。
或
(2)如果没有指定name,查找name或id名为“paymentService”的bean注入。
(3)如果不指定name,查找name或id名为“paymentService3”的bean注入,如果没找到,按类型注入,同@Autowired一样,有2个实现类的情况下会报错。
报错如下:
No qualifying bean of type [com.sitech.miso.payment.common.service.IPaymentService] is defined: expected single matching bean but found 2: paymentService22,paymentService
意思是,对于这2个bean,tomcat启动时不知道到底要选择注入哪一个,因此抛出异常。
(4)再来个id和name交叉相同的情况,修改bean如下:
然后启动,直接报错:
Configuration problem: Bean name 'paymentService2' is already used in this <beans> element。
小结:bean对应的id和name具有几乎相同的地位;在注入时会从id和name中去寻找对应属性名的bean;不同bean的id或name不能相同;同一个bean的id和name可以相同也可以不同。
2、1个接口,2个实现类,使用@Autowired配合@Qualifier注解,如下
(1)通过bean对应id注解
(2)通过bean对应name注解
(3)值得一提的是,如果只用@Autowired注解,默认按照类型注入,如果有多个实现类,会名称为“paymentService2”的bean注入。
小结:配合@Qualifier注解使用时和@Resource效果相同,结论一致。