一、前言
本文,我们来学习 @Resource
注解的使用,通过比较@Autowired
和@Resource
,我们将了解它们的区别、使用方式以及一些小细节。
二、内容
2.1 @Autowired与@Resource
之前,我们在实现类的依赖注入时,会使用 @Autowired
注解来装配bean。而@Resource
注解也可以注入依赖对象,这两个注解的都是实现bean的注入,在日常开发中经常使用。
下面,我们来看一下二者的区别。
首先,@Autowired
注解是Spring
框架自己的:
java
import org.springframework.beans.factory.annotation.Autowired;
而@Resource
注解则是JDK扩展包中的,属于标准注解,由JSR-250(Java规范提案)提供的,更加具有通用性:
java
import javax.annotation.Resource;
@Autowired
注解默认根据类型装配byType
,根据类型在上下文中查找匹配的bean
。如果想根据名称装配,需要配合@Qualifier
注解(指定的name
)进行匹配,匹配不到就会报错;如果设置@Autowired
注解的required
属性为false
(默认为true
),则注入失败时不会抛出异常。这在前一篇文章中记录过。
而@Resource
注解默认根据名称byName
进行装配 ,名称可以通过name
属性进行指定。如果没有指定 name
属性,那么默认取属性名(字段名)作为 name
,按照名称查找。如果还是找不到bean
,此时 Spring会通过类型(byType
)进行装配。
需要注意的是,
@Autowired
注解用在属性上、setter方法上、构造方法上以及构造方法参数上。但是!@Resource
注解只用在属性上和setter方法上。
小结一下:
@Autowired
默认是byType ,可以使用@Qualifier
指定name
,@Resource
默认byName ,如果找不到则byType。@Autowired
是Spring 提供的,@Resource
是JSR-250提供的@Autowired
可以对属性、构造方法、setter方法、构造方法的参数 使用,@Resource
只能对属性、setter方法使用
2.2 引入依赖
Spring6
不再支持JavaEE
,而是支持JakartaEE9
,此时我们需要导入依赖:
xml
<dependency>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
<version>2.1.1</version>
</dependency>
如果是JDK8
,则不需要引入依赖。
Oracle
把JavaEE
贡献给Apache
了,Apache
把JavaEE
的名字改成JakartaEE
了。
2.3 如何使用
(1)根据 name 属性进行装配
还是之前的例子,这里我们通过@Resource
注解的 name
属性来指定 bean
标识:
测试通过:
Config
类的配置很简单:
java@Configuration @ComponentScan({"com.example.dao", "com.example.service"}) public class Config { }
(2)未指定name时,默认将属性名作为 name
当@Resource
注解在使用时,没有指定name属性,就像这样:
那么此时会默认将@Resource
注解标注的属性的名称作为 name
进行查找 bean 并装配。
因此 UserDao
类的 bean 唯一标识名需要写成属性名 userDao
,像这样:
此时测试照样通过:
(3)根据类型进行装配
在使用 @Resource
注解时,什么情况下会根据类型进行装配呢?
事实上,@Resource
注解默认根据名称byName
进行装配 ,如果没有指定 name
属性,那么默认取属性名(字段名)作为 name
,如果还找不到指定的 bean,那么此时会通过类型(byType
)进行装配。
像下面这种情况就是根据类型进行装配:
测试程序运行后也是同样可以的:
我们知道,根据类型注入时,该类型只能有一个 ,否则会报错信息 Injection of resource dependencies failed
。
这里我们测试一把。
再写一个UserDao
接口的实现类:
那么测试程序运行后,效果如下:
2.4 标注在 setter 方法上
前面讲过,@Resource
注解只能标注在属性或setter方法上。
这里,我们再来看一下标注在 setter 方法上的一些细节。
比如说下面这个情况:
这里@Resource
的 name
属性其实跟setter方法的方法名有关。
将setter方法的方法名去掉set后,再将首字母变小写,就是name
的值。比如这里的 setUserDao
方法名去掉 set 后为 UserDao
,再将首字母变小写后,此时userDao
就是 name
的值,因此根据该 name
找到Spring
管理中的 bean
并进行装配。
再举一个例子,如果将 UserDaoForMysql
类的bean表示改为 xxx
。那么 UserService
类的 setter 方法名就需要改为 setXxx
,如下所示:
三、总结
总的来说,更推荐使用@Resource
注解,希望通过本文可以帮助读者理解@Resource
注解的基础使用方法。