在我们的开发项目中,这两个注解是非常常见的,刚学习springboot时,我们可能都是用@Autowired注解,不行就换@Resource,再不行就请求大佬。我们知道这两个注解都可以实现自动装配,但是他们真的就是只是名字不一样功能一样吗?下面我们来一探究竟
1.@Autowired与@Resource分别来自哪里?
我们先来看@Autowired
可以清晰看到,@Autowired注解是来自spring的,那@Resource是不是也是spring呢?我们继续往下看
我们可以发现@Resource并不是来着spring,而是JSR-250,java自己的
2.他们真就是名字不一样作用一样吗?
我们直接上实例,还是一样先看@Autowired
1.我们先定义一个接口,接口名TestAuto
2.我们定义一个实现类TestServiceImpl
3.我们controller里面使用@Autowired
4.测试运行
可以发现成功,没毛病。
紧接着注解更换成@Resource
我们继续上面的步骤
我们发现,一个接口对应一个业务,@Autowired和@Resource都可以成功实现,好像一点问题都没有,那如果一个接口对应多个业务,结果还是这样吗?我们继续探索
5.现在我们多加一个实现类TestTwoServiceImpl
6.我们到controller继续@Autowired
我们发现已经爆红了,运行肯定是出错的,鼠标移上去我们发现他说不能自动装配,发现两个TestAuo类型,意思就是不知道装谁,不知道调那个方法了。
解决办法:我们可以使用@Primay注解 哪一个是优先注入,或使用@Qualifier名字指定一需要注入哪个bean
例如:给TestServiceImpl加个别名
然后在controller中使用@Qualifier来指定一下
现在跑起来是没有问题的,我们来测试一下
欧克了可以跑起来,我们发现@Autowired一开始是默认按照类型去注入,如果是只有一个类型那当然不会报错,现在是两个类型,他就不知道怎么办了,就爆红提示我们要解决一下,我们用了@Qualifier名字指定一下,告诉他要注入哪个bean。
@Autowired 默认按照类型(byType)进行自动装配,如果有多个相同类型的 Bean,则需要通过指定 Bean 的名称或者使用 @Qualifier 注解来指定具体的 Bean
我们换@Resource注解在试一下,看看是不是还是和@Autowired一样呢?
1.首先回到之前,把service别名,和@Qualifier全部去掉
我们发现他不爆红,不爆红是不是可以运行?是不是就没问题呢?我们直接启动
ok报错了,一大串什么意思呢?
解析:@Resource 默认按照名称(byName)进行自动装配,如果没有指定 name 属性,则默认使用被注解字段或方法的名称作为 Bean 的名称进行匹配,找不到又会按照类型去找
如果使用时,没有指定,那么就是按照默认byName,默认去找testAuto这玩意,但是怎么可能找到呢,因为我们刚刚注入bean的是,TestServiceImpl和TestTwoServiceImpl,他们的service是没有指定别名的,默认别名是驼峰命名法。testAuto!=testServiceImpl&&testAuto!=testTwoServiceImpl,所以想找到是不可能的,那他既然通过名字找不到难道就不找吗?不对,他会按照类型继续找,然后就发现TestServiceImpl和TestTwoServiceImpl,两个同样的类型,所以运行报错咯。
解决办法:
一样可以设置名字,刚刚上面我们说了,会默认按照名字去找bean,我们可以给其中一个service设置名字
运行发现是ok的,所以证实我们想法是对的。
当然下面这样写也是ok的,在@service注解就不需要名字了
相信到这里,大家应该知道他们的区别了吧
3.总结
-
来源不同:@Autowired 是 Spring 框架提供的注解,而 @Resource 是 JSR-250 规范中定义的注解。
-
自动装配方式不同:@Autowired 默认按照类型(byType)进行自动装配,如果有多个相同类型的 Bean,则需要通过指定 Bean 的名称或者使用 @Qualifier 注解来指定具体的 Bean;而 @Resource 默认按照名称(byName)进行自动装配,如果没有指定 name 属性,则默认使用被注解字段或方法的名称作为 Bean 的名称进行匹配,如果找不到名称匹配的实例,则会按照类型来进行注入。
-
支持的依赖注入类型不同:@Autowired 只支持 Spring 框架中的依赖注入,而 @Resource 支持 JNDI、EJB 和 Spring 框架中的依赖注入。
-
使用时机不同:@Autowired 适用于 Spring 框架中的依赖注入,而 @Resource 适用于 Java EE 环境(如 Web 应用程序)中的依赖注入。
综上所述,两个注解都可以实现依赖注入,但是在使用时需要根据具体的场景和需求选择合适的注解。本文是自己在学习中的一些理解,如果有错大家可以指出来,谢谢~