以下内容首发于我的个人博客网站:
http://riun.xyz
@Resource和@Autowired的区别:
相同点: 标注在属性或属性的setter方法上,表示向其注入一个对象,省去手动new对象的过程。
不同点:
-
提供方:
-
@Autowired
是由org.springframework.beans.factory.annotation.Autowired
提供,换句话说就是由Spring提供; -
@Resource
是由javax.annotation.Resource
提供,即Java提供,需要JDK1.6及以上。
-
-
注入方式:
-
@Autowired
只按照类型(type)注入,将相同类型的类的对象注入到这个变量中。如果想按名称注入需要结合其他注解。 -
@Resource
默认按照名称(name)注入,也支持按照类型(type)注入。
-
使用情况:
@Autowired
按类型装配依赖对象时,要求依赖对象必须存在。如果启动Spring时未在application上下文中找到此对象,那么将报错无法注入。要避免此情况,必须设置@Autowired(required = false)
。如果我们想按名称装配,必须结合@Qualifier
注解一起使用:@Autowired() @Qualifier("beanName")
。按名称转配时,如果application上下文中没有此名称对应的对象,那么就又会退回到按照类型装配;如果仍没有此类型的对象,则报错xxx could not be found。
@Autowired
private JedisPool jedisPool; // 按照类型装配,将Spring上下文中类型为JedisPool的对象赋给jedisPool变量。
@Autowired
@Qualifier(value = "redisPoolFactory")
private JedisPool jedisPool; // 按照名称装配,将Spring上下文中名称为redisPoolFactory的对象赋给jedisPool变量。若没有此对象,则寻找类型为JedisPool的对象赋给jedisPool变量。
@Resource
有两个最重要的属性:name和type。name属性指定注入的beanName,type属性指定注入的beanType。如果没有指定任何属性,当注解标注在字段上时,就默认取字段名称作为beanName寻找依赖对象;如果按照默认的名称找不到依赖对象,@Resource
会回退到按类型装配,寻找符合该字段属性类型的对象;如果找不到或找到多个,则会报错。一旦指定了name或type属性,就只能按名称装配了。
@Resource
private JedisPoolConfig jedisPool; // 先按照名称装配,找不到名为jedisPool的对象时;再按类型装配,寻找JedisPoolConfig类型的对象
@Resource(name = "redisPoolFactory")
private JedisPool jedisPool; // 只能按照名称寻找名为redisPoolFactory的对象
@Resource
装配顺序:指定name or type?按照name or type装配 :先安装beanName装配,再按照beanType装配。
上述所有按名称装配时均不区分大小写。均既可以作用在属性上,也可以作用在setter方法上。
我推荐使用@Resource
注解,因为这个注解是属于J2EE的,减少了与Spring的耦合。而且在编译器中有些情况使用@Autowired注解时会暴红,但不影响运行;此时使用@Resource
就不会暴红。
小结
@Autowired
只按照类型(type)装配;@Autowired()@Qualifier("beanName")
按照名称(name)装配;无法装配时,退回到按类型装配;如果允许属性null值,则可以设置 @Autowired(required=false)
。
@Resource
没有指定属性或类型时,先按照字段名称装配;找不到时再按照类型装配。一旦指定name属性@Resource(name = "beanName")
或type属性,就只能按名称或类型装配。