Fork me on GitHub

Spring 注释 @Autowired 和@Resource 的区别

一、@Autowired和@Resource都可以用来装配bean,都可以写在字段上,或者方法上。

二、@Autowired属于Spring的;@Resource为JSR-250标准的注释,属于J2EE的。

三、@Autowired默认按类型装配,默认情况下必须要求依赖对象必须存在,如果要允许null值,可以设置它的required属性为false,例如:@Autowired(required=false) ,如果我们想使用名称装配可以结合@Qualifier注解进行使用,如下:

1
2
@Autowired() @Qualifier("baseDao")
private BaseDao baseDao;

四、@Resource,默认安装名称进行装配,名称可以通过name属性进行指定,如果没有指定name属性,当注解写在字段上时,默认取字段名进行安装名称查找,如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。

例如:

1
2
@Resource(name="baseDao")
private BaseDao baseDao;

五、推荐使用:@Resource注解在字段上,这样就不用写setter方法了,并且这个注解是属于J2EE的,减少了与spring的耦合。这样代码看起就比较优雅。

1、@Resource后面没有任何内容,默认通过name属性去匹配bean,找不到再按type去匹配

2、指定了name或者type则根据指定的类型去匹配bean

3、指定了name和type则根据指定的name和type去匹配bean,任何一个不匹配都将报错

然后,区分一下@Autowired和@Resource两个注解的区别:

1、@Autowired默认按照byType方式进行bean匹配,@Resource默认按照byName方式进行bean匹配

2、@Autowired是Spring的注解,@Resource是J2EE的注解,这个看一下导入注解的时候这两个注解的包名就一清二楚了

Spring属于第三方的,J2EE是Java自己的东西,因此,建议使用@Resource注解,以减少代码和Spring之间的耦合。

个人见解:

1、@Autowired和@Resource都是基于@service、@controller、@repository以及xml配置中

2、@Autowired和@Resource匹配的内容取决于@service()括号内的内容或 spring的xml配置里 的id(xml配置优先)

3、如果使用@Resource,请最好这么写@Resource(name=”BWM”),因为他是默认按name匹配的,不填写就按type匹配

4、如果使用@Autowired,请最好不要加@Qualifier(“BWM”),因为他是默认按type匹配的,填写就按name匹配

5、其实@Autowired + @Qualifier(“BWM”) == @Resource(name=”BWM”),@Autowired ==@Resource()或@Resource,用哪个都可以,

6、最好不要这么写 @Resource()+ @Qualifier(“BWM”) ,虽然也可以,但是感觉不伦不类,前者属于j2EE,后者属于spring

7、当 一个接口有两个以上实现类的时候才会用到@Autowired + @Qualifier(“BWM”) 或 @Resource(name=”BWM”),这时,

如果使用的是xml,则不用担心,因为你一定会写id;

如果使用的是@Service(),请注意:最好在括号内写上name,和@Autowired +@Qualifier(“BWM”)或Resource(name=”BWM”)成对出现,增强可读性,避免出错,

因为有一种特殊情况会使你出错,spring@Service生成bean的命名规则:当类的名字是以两个或以上连续的大写字母开头的话,bean的名字会与类名保持一致,首字母不小写

8、当一个接口只有一个实现类,@Autowired和@Resource没有区别,但是最好用@Autowired,原因请看下文

9、@Resource默认按name匹配,,当有一个接口有多个实现类的时候,引用都是一个接口,不好区分,才使用name区分,这种情况使用@Resource和@Autowired都可以,推荐使用@Resource,且都是按name匹配,一般不用type匹配,引用的是同一个接口,同一个type

还有一种方式:使用byType类型时,使用@Service+@Primary组合,一个接口当有多个实现类,,@Primary强制指定一个实现类

10、@Autowired默认按type匹配,,当有一个接口只有有一个实现类的时候,引用是一个接口,只有一个实现类,没必要使用name区分,这种情况使用@Resource和@Autowired都可以,推荐使用@Autowired,一般都是按type匹配,也可以按name匹配,比较麻烦不推荐

(比如:一个与世隔绝的村子,只有一个姓李的人,大家叫他“老李”,都知道他是谁,就没必要叫名字。但是这个村要是有2-100姓李的,你叫“老李”,大家就不知道是叫谁了,这时候就要加名字。type=姓 name=名;如果有个姓李的,十分厉害,十分有名,那可能叫“老李”,就特指他一个人,优先级最高 ,等价于@Primary)

总结:

当一个接口只有一个实现类,推荐使用@Autowired,默认byType注入,不一定 真的byType,可以修改为byName,@Resource同理;

当一个接口有多个实现类,推荐使用@Resource,默认byName注入;

具体情况具体分析 : 比如当一个接口有多个实现类,用@Primary 告诉spring 在犹豫的时候(byName是不会犹豫的,会确定一个唯一实现类,@Primary没有意义)优先选择哪一个具体的实现。spring优先注入@Primary修饰的那个;或者使用@Qualifier来标注需要注入的类。

@Service是注入,生成bean实例,既有type也有name. @Service标注名称,如@Service(“Benz”),则bean的名称就是Benz,如果不标注,@Service(),spring会默认注入一个beanName,要注意特殊情况,看上文

@Autowired和@Resource只是查找匹配,然后给属性赋值。private Car car;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@Service
public class CarFactory {
@Resource(name="benz")//byName匹配,此时beanName=benz;如果将(name="benz")去掉,beanName=car,即属性名;只要byName匹配不到,就会使用byType匹配
private Car car;

public String toString(){

return car.carName();
}

public void Test(){
System.out.println("it is ok!");
}

}

如果@Resource(name=”benz”)换成@Autowired+@Qualifier(“benz”),此时也是按照byName,此时beanName=benz,如果再去掉@Qualifier(“benz”),就是byType匹配,beanType=XXX.Car.class

注意 :@Autowired和@Resource只是匹配beanName,决定注入beanName的是@service()括号内的name(没有的话spring会自动生成一个,有一个特殊情况请看上文)或 spring的xml配置里 的id=name(xml配置优先)

参考链接:

https://www.cnblogs.com/StarkMorgan/p/10408255.html

https://www.cnblogs.com/leiOOlei/p/3713779.html

相关文章

微信打赏

赞赏是不耍流氓的鼓励

评论系统未开启,无法评论!