Spring 注释 @Autowired 和@Resource 的区别
一、@Autowired和@Resource都可以用来装配bean,都可以写在字段上,或者方法上。
二、@Autowired属于Spring的;@Resource为JSR-250标准的注释,属于J2EE的。
三、@Autowired默认按类型装配,默认情况下必须要求依赖对象必须存在,如果要允许null值,可以设置它的required属性为false,例如:@Autowired(required=false) ,如果我们想使用名称装配可以结合@Qualifier注解进行使用,如下:
1 | @Autowired() @Qualifier("baseDao") |
四、@Resource,默认安装名称进行装配,名称可以通过name属性进行指定,如果没有指定name属性,当注解写在字段上时,默认取字段名进行安装名称查找,如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。
例如:
1 | @Resource(name="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配置里
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 | @Service |
如果@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配置里
参考链接:
https://www.cnblogs.com/StarkMorgan/p/10408255.html
https://www.cnblogs.com/leiOOlei/p/3713779.html
相关文章

赞赏是不耍流氓的鼓励
评论系统未开启,无法评论!