@Resource、@Inject和@Autowired的区别
代码背景
定义一个接口
首先定义一个接口:
两个实现方法
定义了一个MyService接口,其中有一个方法,这里有两个实现:
第一个实现
第二个实现
测试
三种注解
使用@Inject注解
@Inject
是JSR-330规范中定义的注解,它与@Autowired
的作用相同,同样是用于依赖注入。实际上,Spring也支持@Inject
注解,并且与@Autowired
的功能几乎一样。
使用@Resource注解
@Resouce注解默认通过名称注入,如名称无法找到,则通过类型注入(名称 -》类型)。
这里两个名称分别是myServiceImpl01和myService02,因此通过名称来找,找不到,所以会通过类型来找。然后运行后会报错找到了两个:
这个时候要想正常运行的话,就把这个实现类删除一个,要么就把这里变成其中的一个名字:
@Resource
是Java标准的注解(JSR-250),也是用于依赖注入的一种方式。
它可以根据名称(byName)或者类型(byType)来进行依赖注入。如果指定了name属性,则会根据名称进行注入;否则,会根据类型进行注入。
需要注意的是,@Resource
注解并不是Spring框架的特定功能,而是Java标准的一部分。
使用@Autowired注解
默认通过类型注入,如存在多个类型则通过名称注入(类型 -》名称):
这个时候会报错的,找到了两个:
Autowired
是Spring的核心注解之一,它是基于类型(byType)进行自动装配。
当你在一个类的字段、构造函数或者Setter方法上添加@Autowired
注解时,Spring会尝试查找并注入与该字段、构造函数参数或者Setter方法参数类型匹配的Bean。
如果找到多个匹配的Bean,则会根据Bean的名称或者限定符(Qualifier)来进行选择。
解决方案
它的提示是,可以使用@Primary注解或者通过@Qualifier注解来解决。
这里修改成正确的名称,再次运行:
使用@Qualifier注解来解决
或者通过指定用哪个bean,来解决:
@Qualifier注解表示限制、约定使用哪个bean。
使用@Primary注解来解决
如果不使用这个方法,可以将其中一个bean设置为最主要的bean:
相同点
三者都是在Spring框架中用于依赖注入的注解,它们的作用都是将依赖对象自动注入到相应的类中。尽管它们在实现上有一些差异,但在一般情况下,它们可以互相替换使用。
区别
来源不同
@Resource是Java EE规范定义的注解,@Autowired是Spring框架提供的注解, @Inject 是JSR-330规范中的注解
注入方式不同
@Resource是按照名称进行注入的,它可以通过name
属性指定具体要注入的资源名称,如果未指定名称,则按照类型进行注入。
而@Autowired是按照类型进行注入的,它会根据类型在容器中找到对应的实例进行注入。不行的话会根据名称来进行注入。
支持的容器不同
@Resource是Java EE规范的一部分,因此它可以在遵循Java EE规范的容器中使用,如Tomcat、WebLogic等。
而@Autowired是Spring框架提供的,因此它主要用于Spring容器中。
为什么使用@Resource
使用**@Resource的一个常见场景是在使用Java EE容器时,它提供了一种方便的方式来注入资源,如数据库连接**、JMS(Java消息服务)队列等。
此外,@Resource可以根据名称进行注入,这在存在读个相同类型的实例时可以更加灵活地控制注入的资源。
注意
需要注意的是,如果你在使用Spring框架,通常更推荐使用@Autowired注解,因为它提供了更多的功能和选项,而且与Spring的其他特性更好地集成。
只有在特定的情况下,或者在使用Java EE容器时,才建议使用@Resource。