当前位置: 首页 > news >正文

为什么IDEA提示不推荐@Autowired?如果使用@Resource呢?

因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩技术分享

点击关注#互联网架构师公众号,领取架构师全套资料 都在这里

0、2T架构师学习资料干货分

上一篇:2T架构师学习资料干货分享

大家好,我是互联网架构师!

来源:juejin.cn/post/7463352165487935542

前言

在使用 Spring 框架时,依赖注入(DI)是一个非常重要的概念。通过注解,我们可以方便地将类的实例注入到其他类中,提升开发效率。

@Autowired又是被大家最为熟知的方式,但很多开发者在使用 IntelliJ IDEA 时,常常看到 IDEA 提示不推荐使用@Autowired,这是为什么呢?

今天讲一下我对于@Autowired字段注入的理解。


1. 为什么不推荐使用@Autowired?

1.1. 隐式依赖

@Autowired会根据类型自动注入依赖,可能导致依赖不明确。特别是在存在多个符合类型的候选对象时,可能会导致注入失败或错误地注入实例。

1.2. 循环依赖

@Autowired可能导致循环依赖,尤其在单例 Bean 中,虽然 Spring 有解决方案,但仍需额外处理。

1.3. 生命周期不透明

通过@Autowired注入的 Bean 由 Spring 管理,类无法显式了解其生命周期。相比之下,构造器注入可以显式管理依赖的生命周期。

1.4. 不符合不可变性原则

字段注入使得依赖关系在对象生命周期内可能发生变化,而构造器注入确保依赖在对象创建时设定,符合不可变性原则。

经常看到的争议点:不推荐使用@Autowired,所以就使用@Resource(使用@Resource时,IDEA不会有波浪线提示)。


2. @Autowired和@Resource的基本用法

2.1. @Autowired

@Autowired是 Spring 提供的注解,用于自动注入依赖项。Spring 会根据类型(默认情况下)或者名称(通过@Qualifier)来自动注入所需的 Bean。

@Autowired private UserService userService;

在这个例子中,Spring 会自动将UserService类型的 Bean 注入到userService属性中。

2.2. @Resource

@Resource是 Java 规范的一部分,来自javax/jakarta.annotation包,它更注重按照名称来注入 Bean。默认情况下,它会尝试按名称匹配,但如果没有找到匹配的名称,再通过类型注入。

@Resource private UserService userService;

@Autowired不同@Resource会首先查找名为userService的 Bean,如果找不到,再通过类型注入。

可以看出其实两者本质上是没有区别的,只是匹配顺序不一样。


3. @Autowired和@Resource实测对比

假如有一个接口类,如下:

@Service publicinterfaceUserService{ // 用户服务... }

两个实现类,如下:

@Component publicclassUserServiceImplimplementsUserService{ // 实现细节 } @Component publicclassAnotherUserServiceImplimplementsUserService{ // 另一个实现 }
3.1. 使用@Autowired做测试

在测试接口里面加入@Autowired,如下:

/** * 测试接口 */ @RestController("test") publicclassTestController{ @Autowired private UserService userService; }

启动项目,控制台输出错误,如下:

错误提示:需要一个bean,但是找到了两个bean。

修改之后指定具体的bean名,如下:

@RestController("test") publicclassTestController{ @Autowired // @Qualifier("userServiceImpl") // 或者使用Qualifier来指定bean名 private UserService userServiceImpl; }

启动项目,项目正常启动,断点测试如下:

正常获取到需要的bean实例。

3.2. 使用@Resource做测试

在测试接口里面加入@Resource,如下:

/** * 测试接口 */ @RestController("test") publicclassTestController{ @Resource private UserService userService; }

启动项目,控制台输出错误,如下:

错误提示:需要一个bean,但是找到了两个bean。

修改之后指定具体的bean名,如下:

@RestController("test") publicclassTestController{ @Resource // @Resource(name = "userServiceImpl") // 或者使用name来指定bean名 private UserService userServiceImpl; }

启动项目,项目正常启动,断点测试如下:

正常获取到需要的bean实例。

可以看出实际上@Autowired@Resource的使用效果是一样的。(@Resource并不优于@Autowired,两者都是基于字段注入。甚至于在Spring框架中,@Autowired性能更好,例如:自动装配的细粒度控制 。)


4. 推荐注入的方式

构造器注入是推荐的首选方式,尤其在处理复杂依赖关系、不可变对象、单元测试等场景时,构造器注入非常有用。

4.1. 推荐原因
  • 显式依赖关系:构造器注入使依赖关系在对象创建时就显式地列出,代码更清晰。

  • 不可变性:依赖可以声明为 final,避免修改。

  • 避免循环依赖:能及时发现并避免循环依赖问题。

  • 明确依赖关系:构造器清晰暴露依赖,增强代码可读性。

4.2. 示例
@RestController("test") publicclassTestController{ privatefinal UserService userService; publicTestController(UserService userServiceImpl){ this.userService = userServiceImpl; } } // 或者使用lombok简化代码。 @RestController("test") @RequiredArgsConstructor publicclassTestController{ privatefinal UserService userServiceImpl; }

伪逻辑说明:

  • 显式依赖关系:应该关注的是,整个项目的代码规范,而不是针对具体的某一个类去优化,使用构造器注入。

  • 不可变性:应该关注的是,合理的设计,项目中bean在初始时,如果使用@Autowired注入某个类,就应该不在初始化期间去修改它。

  • 避免循环依赖:也是和项目的架构相关,如果无法中设计上避免,也可以通过代理和懒加载去解决。

  • 明确依赖关系:如果项目类名命名规范,不使用相同的类名,或者使用一些前缀后缀去区分,也能够不影响依赖关系。


5. 构造器一定优于@Autowired吗?

@Autowired在一些方面要优于构造器注入?

  • 简化代码:自动注入依赖,无需手动编写构造器或 setter 方法,代码更简洁。

  • 快速开发:灵活且快速,不需要修改构造函数,可以直接通过字段注入依赖。

  • 自动依赖管理:Spring 自动管理依赖,简化了依赖的选择和注入过程。

  • 避免构造函数冗长:对于依赖较多的类,字段注入避免了构造函数过长的问题。


结语

虽然 IDEA 提示不推荐使用@Autowired,但这并不意味着它是一个糟糕的选择。不同的注入方式有其各自的优缺点,选择依赖注入方式时,应该根据项目规模、复杂性以及团队编码习惯来决定,而不是盲目跟随趋势。

认说到底,程序从职场角度看,公司这样做很可能是想“信息差”捞点回本。建议保存所有当年的交接记录、邮件、IM聊天截图,必要时走仲裁流程,不然这种事开了先例,下一个就可能是别人员写代码要留注释,职场上做事也要留痕迹。只有手里握着证据,才能不被随便背锅。,

1、2T架构师学习资料干货分享

2、10000+TB资源,阿里云盘,牛逼!!

3、基本涵盖了Spring所有核心知识点总结

· END ·

最后,关注公众号互联网架构师,在后台回复:2T,可以获取我整理的 Java 系列面试题和答案,非常齐全。

如果这篇文章对您有所帮助,或者有所启发的话,帮忙扫描上方二维码关注一下,您的支持是我坚持写作最大的动力。

求一键三连点赞、转发、在看

http://www.cnnetsun.cn/news/80256.html

相关文章:

  • CloudStream媒体文件管理终极指南:从混乱到有序的完整解决方案
  • 时序数据可视化终极指南:AI工具让数据分析如此简单
  • 智能体协作框架设计:多个Anything-LLM实例分工合作
  • Gin 真的是“真菌”吗?—— 一篇引发热议的“反 Gin”檄文解读
  • 在海康工作是怎么样的?
  • 2025年12月语言榜单揭秘:Python 确实强得离谱!
  • Ollama模型列表查看及导入Anything-LLM的方法详解
  • 被困在算法里的不只是外卖骑手,还有广大自媒体人
  • 鼠鬚管输入法完整指南:快速安装与个性化配置
  • GPT-5.2 正式发布!开启 AI 职场效率革命新时代
  • VentoyPlugson终极指南:快速掌握图形化配置工具的完整使用方法
  • 校园外卖|基于springboot + vue校园外卖系统(源码+数据库+文档)
  • 企业工资管理|基于springboot + vue企业工资管理系统(源码+数据库+文档)
  • Node.js多线程调试实战:从困惑到精通的完整指南
  • 计算筑基 智创未来,华为以数智力量擘画三湘大地创新蓝图
  • 7、高级计算器:从语法解析到函数求值的全面解析
  • 9、MySQL SQL 解析器深度剖析
  • Cartographer时间同步技术:如何解决多传感器数据融合的核心难题
  • 43、高效运维与快速输入技巧
  • 17、Bison语法错误处理与位置信息应用
  • 19、解析器技术:GLR 解析与 C++ 解析器的深入探索
  • 46、Bash编程:函数使用、通配符与正则表达式及相关参考
  • 48、Bash命令参考:测试操作符、I/O重定向与格式化输出
  • 52、深入探索bash:从源码构建到高级应用
  • B站广告屏蔽神器:小电视空降助手让你的观影体验重回纯净
  • Citra模拟器联机游戏终极指南:5步快速实现远程对战
  • 从实战角度解析sktime软依赖管理:构建稳健的时间序列分析环境
  • 第七十五篇:Kubernetes入门:Pod, Deployment, Service核心概念深度解析
  • 快速获取Windows Server 2022官方镜像的完整指南
  • Triton C++客户端异步推理:解锁高性能AI服务的终极指南