为什么 Spring 和 IDEA 都推荐使用 @Resource注解而不是@Autowired?

简介: 为什么 Spring 和 IDEA 都推荐使用 @Resource注解而不是@Autowired?

大家在使用IDEA开发的时候有没有注意到过一个提示,在字段上使用Spring的依赖注入注解@Autowired后会出现警告,但是使用@Resource却不会出现,今天我们来聊聊这两者的区别。

1.0 @Autowired 和 @Resource简单介绍

@Autowired@Resource 都是 Spring/Spring Boot 项目中,用来进行依赖注入的注解。它们都提供了将依赖对象注入到当前对象的功能,但二者却有众多不同。

1.1 @Autowired 和 @Resourceu区别

@Autowired 和 @Resource 的区别主要体现在以下 5 点:

  • 来源不同;
  • 依赖查找的顺序不同;
  • 支持的参数不同;
  • 依赖注入的支持不同;
  • 编译器 IDEA 的提示不同。

1.来源不同

@Autowired@Resource 来自不同的“父类”,其中 @Autowired 是 Spring 定义的注解,而 @ResourceJava 定义的注解,它来自于 JSR-250(Java 250 规范提案)。

小知识:JSR 是 Java Specification Requests 的缩写,意思是“Java 规范提案”。任何人都可以提交 JSR 给 Java 官方,但只有最终确定的 JSR,才会以 JSR-XXX 的格式发布,如 JSR-250,而被发布的 JSR 就可以看作是

Java 语言的规范或标准

2.依赖查找顺序不同

依赖注入的功能,是通过先在 Spring IoC 容器中查找对象,再将对象注入引入到当前类中。而查找有分为两种实现:按名称(byName)查找或按类型(byType)查找,其中 @Autowired 和 @Resource 都是既使用了名称查找又使用了类型查找,但二者进行查找的顺序却截然相反。

2.1 @Autowired 查找顺序

@Autowired 是先根据类型(byType)查找,如果存在多个 Bean 再根据名称(byName)进行查找,它的具体查找流程如下:

关于以上流程,可以通过查看 Spring 源码中的 org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#postProcessPropertyValues 实现分析得出,源码执行流程如下图所示:

2.2 @Resource 查找顺序

@Resource 是先根据名称查找,如果(根据名称)查找不到,再根据类型进行查找,它的具体流程如下图所示:

关于以上流程可以在 Spring 源码的 org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#postProcessPropertyValues 中分析得出。虽然 @Resource 是 JSR-250 定义的,但是由 Spring 提供了具体实现,它的源码实现如下:

2.3 查找顺序小结

由上面的分析可以得出:

@Autowired 先根据类型(byType)查找,如果存在多个(Bean)再根据名称(byName)进行查找;


@Resource 先根据名称(byName)查找,如果(根据名称)查找不到,再根据类型(byType)进行查找。

3.支持的参数不同

@Autowired 和 @Resource 在使用时都可以设置参数,比如给 @Resource 注解设置 name 和 type 参数,实现代码如下:

@Resource(name = "userinfo", type = UserInfo.class)
private UserInfo user;

但二者支持的参数以及参数的个数完全不同;

其中 @Autowired 只支持设置一个 required 的参数

而 @Resource 支持 7 个参数,支持的参数如下图所示:

4.依赖注入的支持不同

@Autowired 和 @Resource 支持依赖注入的用法不同,常见依赖注入有以下 3 种实现:

属性注入
构造方法注入
Setter 注入

这 3 种实现注入的实现代码如下。

a) 属性注入

@RestController
public class UserController {
    // 属性注入
    @Autowired
    private UserService userService;
    @RequestMapping("/add")
    public UserInfo add(String username, String password) {
        return userService.add(username, password);
    }
}

b) 构造方法注入

@RestController
public class UserController {
    // 构造方法注入
    private UserService userService;
    @Autowired
    public UserController(UserService userService) {
        this.userService = userService;
    }
    @RequestMapping("/add")
    public UserInfo add(String username, String password) {
        return userService.add(username, password);
    }
}

c) Setter 注入

@RestController
public class UserController {
    // Setter 注入
    private UserService userService;
    @Autowired
    public void setUserService(UserService userService) {
        this.userService = userService;
    }
    @RequestMapping("/add")
    public UserInfo add(String username, String password) {
        return userService.add(username, password);
    }
}

其中,@Autowired 支持属性注入、构造方法注入和 Setter 注入,而 @Resource 只支持属性注入和 Setter 注入,当使用 @Resource 实现构造方法注入时就会提示以下错误:

5.编译器提示不同

当使用 IDEA 专业版在编写依赖注入的代码时,如果注入的是 Mapper 对象,那么使用 @Autowired 编译器会提示报错信息,报错内容如下图所示:

虽然 IDEA 会出现报错信息,但程序是可以正常执行的。然后,我们再将依赖注入的注解更改为 @Resource 就不会出现报错信息了,具体实现如下:

总结

@Autowired 和 @Resource 都是用来实现依赖注入的注解(在 Spring/Spring Boot 项目中),但二者却有着 5 点不同:

来源不同@Autowired 来自 Spring 框架,而 @Resource 来自于(Java)JSR-250

@Autowired功能虽说非常强大,但是也有些不足之处。比如它跟Spring强耦合了,如果换成了其他框架,功能就会失效。而@Resource是JSR-250提供的,它是Java标准,绝大部分框架都支持。

依赖查找的顺序不同@Autowired 先根据类型再根据名称查询,而 @Resource 先根据名称再根据类型查询

Autowired默认按byType自动装配,而@Resource默认byName自动装配。

支持的参数不同:@Autowired 只支持设置 1 个参数,而 @Resource 支持设置 7 个参数

@Autowired只包含一个参数:required,表示是否开启自动准入,默认是true。而@Resource包含七个参数,其中最重要的两个参数是:name 和 type。

依赖注入的用法支持不同@Autowired 既支持构造方法注入,又支持属性注入和 Setter 注入,而 @Resource 只支持属性注入和 Setter 注入;

@Autowired能够用在:构造器、方法、参数、成员变量和注解上,而@Resource能用在:类、成员变量和方法上。

编译器 IDEA 的提示不同当注入 Mapper 对象时,使用 @Autowired 注解编译器会提示错误,而使用 @Resource 注解则不会提示错误

@Autowired如果要使用byName,需要使用@Qualifier一起配合。而@Resource如果指定了name,则用byName自动装配,如果指定了type,则用byType自动装配。

记录学习;文章来源


相关文章
|
Java Spring
【Spring配置】idea编码格式导致注解汉字无法保存
问题一:对于同一个项目,我们在使用idea的过程中,使用汉字注解完后,再打开该项目,汉字变成乱码问题二:本来a项目中,汉字注解调试好了,没有乱码了,但是创建出来的新的项目,写的注解又成乱码了。
|
前端开发 Java 开发者
这款免费 IDEA 插件让你开发 Spring 程序更简单
Feign-Helper 是一款支持 Spring 框架的 IDEA 免费插件,提供 URL 快速搜索、Spring Web Controller 路径一键复制及 Feign 与 Controller 接口互相导航等功能,极大提升了开发效率。
3775 1
|
Java 测试技术 程序员
为什么Spring不推荐@Autowired用于字段注入?
作为Java程序员,Spring框架在日常开发中使用频繁,其依赖注入机制带来了极大的便利。然而,尽管@Autowired注解简化了依赖注入,Spring官方却不推荐在字段上使用它。本文将探讨字段注入的现状及其存在的问题,如难以进行单元测试、违反单一职责原则及易引发NPE等,并介绍为何Spring推荐构造器注入,包括增强代码可读性和维护性、方便单元测试以及避免NPE等问题。通过示例代码展示如何将字段注入重构为构造器注入,提高代码质量。
708 1
|
Java 应用服务中间件 Maven
idea+maven+tomcat+spring 创建一个jsp项目
这篇文章介绍了如何在IntelliJ IDEA中使用Maven和Tomcat创建一个JSP项目,包括配置Maven依赖、设置Tomcat服务器、编写JSP页面、创建控制器和配置文件,以及项目的运行结果。
1281 0
idea+maven+tomcat+spring 创建一个jsp项目
|
Java 关系型数据库 开发工具
idea创建不了spring2.X版本,无法使用JDK8,最低支持JDK17 , 如何用idea创建spring2.X版本,使用JDK8解决方案
本文提供了解决方案,如何在IDEA中创建Spring 2.X版本的项目并使用JDK8,尽管Spring 2.X已停止维护且IDEA不再直接支持,通过修改pom.xml或使用阿里云的国内源来创建项目。
3023 0
idea创建不了spring2.X版本,无法使用JDK8,最低支持JDK17 , 如何用idea创建spring2.X版本,使用JDK8解决方案
Java系列之 IDEA 为类 和 方法设置注解模板
这篇文章介绍了如何在IntelliJ IDEA中为类和方法设置注解模板,包括类模板的创建和应用,以及两种不同的方法注解模板的创建过程和实际效果展示,旨在提高代码的可读性和维护性。
|
XML JSON Java
使用IDEA+Maven搭建整合一个Struts2+Spring4+Hibernate4项目,混合使用传统Xml与@注解,返回JSP视图或JSON数据,快来给你的SSH老项目翻新一下吧
本文介绍了如何使用IntelliJ IDEA和Maven搭建一个整合了Struts2、Spring4、Hibernate4的J2EE项目,并配置了项目目录结构、web.xml、welcome.jsp以及多个JSP页面,用于刷新和学习传统的SSH框架。
656 0
使用IDEA+Maven搭建整合一个Struts2+Spring4+Hibernate4项目,混合使用传统Xml与@注解,返回JSP视图或JSON数据,快来给你的SSH老项目翻新一下吧
|
Java Spring
idea新建spring boot 项目右键无package及java类的选项
idea新建spring boot 项目右键无package及java类的选项
1024 5
|
监控 IDE Java
探索 IntelliJ IDEA 中 Spring Boot 运行配置选项及其作用
探索 IntelliJ IDEA 中 Spring Boot 运行配置选项及其作用
2235 0
IDEA项目所有的注解都不起作用,整个项目突然爆红
IDEA项目所有的注解都不起作用,整个项目突然爆红
858 0
IDEA项目所有的注解都不起作用,整个项目突然爆红