Spring Boot `@Service` 互相调用全攻略:`@Autowired` vs `@Resource`

Spring Boot @Service 互相调用全攻略:@Autowired vs @Resource

在日常写 Spring Boot 项目的时候,经常会遇到一个问题:多个 @Service 之间需要互相调用,到底该怎么写才优雅?用 @Autowired?用 @Resource?循环依赖怎么办?

本文就带你一口气整清楚,并配合 Demo 来对比,最后还会总结最佳实践。


在这里插入图片描述

1. 基础:@Service 是什么?

在 Spring 里,@Service 其实就是一个 特殊的 Bean。它被 Spring 容器管理,创建、销毁、注入都由 Spring 来完成。
所以,不管你用 @Autowired 还是 @Resource,本质上都是 依赖注入(Dependency Injection)


2. @Autowired:Spring 派来的助手

2.1 特点

  • 默认按照 类型(byType)注入;
  • 如果有多个同类型的 Bean,会报错,需要用 @Qualifier 指定;
  • 支持构造器、字段、Setter 注入;
  • 可以加 required = false,让依赖变成可选。

2.2 Demo

@Service
public class UserService {public String getUserName(Long id) {return "User-" + id;}
}@Service
public class OrderService {private final UserService userService;// 构造器注入(推荐 ✅)@Autowiredpublic OrderService(UserService userService) {this.userService = userService;}public void createOrder(Long userId) {System.out.println("订单用户: " + userService.getUserName(userId));}
}

3. @Resource:JDK 官方背书

3.1 特点

  • 来自 JSR-250 标准,算是“官方背书”;
  • 默认按照 名称(byName)注入,找不到时再按照类型;
  • 常用在字段 / Setter 注入;
  • 不支持 required = false

3.2 Demo

@Service
public class UserService {public String getUserName(Long id) {return "User-" + id;}
}@Service
public class OrderService {@Resourceprivate UserService userService; // 按字段名 userService 找 Beanpublic void createOrder(Long userId) {System.out.println("订单用户: " + userService.getUserName(userId));}
}

3.3 多实现类场景

@Service("vipUserService")
public class VipUserService extends UserService {@Overridepublic String getUserName(Long id) {return "VIP-" + id;}
}@Service
public class OrderService {@Resource(name = "vipUserService")private UserService userService;public void createOrder(Long userId) {System.out.println("订单用户: " + userService.getUserName(userId));}
}

4. 循环依赖问题

有时候,你写着写着,就会掉进一个坑:两个 Service 互相依赖

@Service
public class AService {@Autowiredprivate BService bService;public void a() {System.out.println("A 调用");bService.b();}
}@Service
public class BService {@Autowiredprivate AService aService;public void b() {System.out.println("B 调用");aService.a();}
}

结果:启动失败,提示循环依赖。

4.1 循环调用的可视化

AServiceBService调用 b()调用 a()再次调用 b()再次调用 a()无限递归,最终 StackOverflow 或启动失败AServiceBService

4.2 解决方法

  • 重构代码(最佳 ✅):抽出公共逻辑放到 CService,避免直接互调。
  • 延迟注入(权宜之计):在其中一个依赖上加 @Lazy
@Service
public class BService {private final AService aService;public BService(@Lazy AService aService) {this.aService = aService;}public void b() {System.out.println("B 调用");aService.a();}
}

5. 总结:到底用哪个?

  • 单实现类场景
    @Autowired@Resource 都行,推荐 构造器 + @Autowired

  • 多实现类场景
    @Resource(name="xxx") 更直观;
    @Autowired + @Qualifier("xxx") 也可以。

  • 循环依赖
    优先考虑 重构;不得已时用 @Lazy


6. 最佳实践建议

  1. 优先构造器注入,少用字段注入
    字段注入虽然写起来爽,但对测试和维护都不友好。

  2. @Autowired vs @Resource 没有绝对优劣

    • 倾向 Spring → 用 @Autowired
    • 倾向标准化 → 用 @Resource
  3. 不要用循环依赖当“快捷方式”
    那通常说明设计有问题。


@Autowired@Resource 之间纠结,远不如搞清楚你的代码结构更重要。
真正能写好 Service 之间调用的,不是靠注解,而是靠 架构设计


实用小工具

App Store 截图生成器、应用图标生成器 、在线图片压缩和 Chrome插件-强制开启复制-护眼模式-网页乱码设置编码
乖猫记账,AI智能分类的最佳聊天记账App。
Elasticsearch可视化客户端工具

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/923714.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/923714.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c过渡c++应知应会(2)

c过渡c应知应会(2)1.缺省参数2.函数重载3.引用4.inline1.缺省参数 缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实参,则采用该形参的缺省值,否则使用指定的实参,缺…

SSH连接排故排查

文章目录SSH连接排故排查案例1:解决思路排故过程故障模拟SSH连接排故排查 案例1: 你是某在线教育公司的运维工程师,负责维护 3 台应用服务器。今日上午 9 点,开发团队反馈无法通过 SSH 连接 10.1.8.10 服务器部署代码。该服务器…

Python爬虫实战——使用NetNut网页解锁器获取亚马逊电商数据的入门指南

摘要在当今数字化时代,电商数据蕴含着巨大的商业价值。亚马逊作为全球知名的电商平台,其上的商品信息、用户评价等数据对于市场分析、竞品研究等具有重要意义。然而,由于反爬虫机制的存在,直接获取亚马逊电商数据并非易事。本文将…

汽车多核架构中内存系统故障检测的改进算法

摘要随着半导体行业向纳米级方向发展,多核架构已成为主流趋势。然而,这一趋势也使得多核处理器面临诸多挑战,在一定程度上限制了其性能发挥。目前,汽车行业中的混合安全关键型系统普遍采用多核处理器。为满足新兴自动驾驶等级的需…

VastBase数据库Crash后使用gdb收集coredump信息

VastBase数据库Crash后使用gdb收集coredump信息🐘 数据库版本:VastBase G100 V3.0.8检查数据库崩溃后生成的core文件: [vbdbadbhost vastbase]$ ll -h core* -rw------- 1 vbdba vbdba 62G Aug 20 20:02 core-vastbase-162199-2025_08_20_19_…

【LeetCode 每日一题】2749. 得到整数零需要执行的最少操作数

Problem: 2749. 得到整数零需要执行的最少操作数 文章目录整体思路完整代码时空复杂度时间复杂度:O(1)空间复杂度:O(1)整体思路 这段代码旨在解决一个具有数学和位运算性质的问题:给定两个整数 num1 和 num2,找到最小的正整数 k&…

安卓开发工程师中高级知识点 —— 系统底层安全方向

一、AIDL 通信 Android Interface Definition Language 基于 Binder 实现跨进程通信(IPC),核心是通过定义接口生成代理类,屏蔽底层 Binder 通信细节 适用于跨进程服务调用(如系统服务、多App协作)。常见于后…

动环监控系统-机房高效运维

动环监控系统(全称为动力环境监控系统)是机房高效运维的核心工具,通过集成动力、环境、安防、IT设备等模块,结合智能告警、AI分析、3D可视化等技术,实现机房的全方位监控与管理。动力系统监控供电设备:实时…

知微传感Dkam系列3D相机SDK例程篇:CSharp设置相机工作模式

设置3D相机触发模式 写在前面 本人从事机器视觉细分的3D相机行业。编写此系列文章主要目的有: 1、便利他人应用3D相机,本系列文章包含公司所出售相机的SDK的使用例程及详细注释;2、促进行业发展及交流。设置触发模式及API说明 触发模式说明 知…

PHP 常用函数及用法

文章目录PHP 常用函数及用法一、字符串处理函数1. 字符串基础操作2. 字符串查找与替换3. 字符串分割与连接4. 字符串大小写转换5. 字符串格式化二、数组操作函数1. 数组基础操作2. 数组遍历与查找3. 数组修改与排序4. 数组过滤与合并三、文件操作函数1. 文件读写2. 文件和目录信…

yum命令--obsoletes与--allowerasing两者的区别

在 YUM(Yellowdog Updater Modified)包管理工具中,–obsoletes 和 --allowerasing 是两个与包升级 / 安装相关的选项,它们的功能和使用场景有明显区别: 1. --obsoletes(默认启用)作用&#xff1…

Day24_【深度学习(3)—PyTorch使用(1)—张量的创建和类型转换】

一、创建张量1.张量基本创建方式torch.tensor 根据指定数据创建张量 (最重要)torch.Tensor 根据形状创建张量, 其也可用来创建指定数据的张量torch.IntTensor、torch.FloatTensor、torch.DoubleTensor 创建指定类型的张量1.1 torch.tensor# 方式一&…

阿里云图像编辑大模型开发部署

与阿里云一起轻松实现数智化让算力成为公共服务:用大规模的通用计算,帮助客户做从前不能做的事情,做从前做不到的规模。让数据成为生产资料:用数据的实时在线,帮助客户以数据为中心改变生产生活方式创造新的价值。图像…

查看磁盘分区并新建一个分区,挂载分区

linux系统磁盘df -h查看文件系统的磁盘的空间占用情况,常用于快速检查磁盘使用率:df -h-h是说把磁盘空间以G位单位,如果直接用df也是可以的,只不过单位是块,看的不明显du -sh /home/查看/home目录下总共占用了多大的空…

vscode单击暂时预览文件 双击持续打开文件

直接单击文件列表中的文件,会在编辑器中以预览模式打开 文件标签会显示为斜体,表示是预览状态 当您单击另一个文件或开始编辑时,预览文件会自动关闭 在 settings.json 中添加,mac通过cmd,实现。 json {"workbench.editor.ena…

设计模式-桥接模式04

什么是桥接模式? 桥接模式就是把事物的两个方面(两个变化的维度)分开管理,让它们可以分别自由变化,然后通过一个“桥”把它们连接起来。举个生活中的例子 想象一下你在买鞋子: 鞋子有不同的款式&#xff08…

群晖企业级NAS :从中小企业效率工具到核心业务数据基石

在数字化转型加速的今天,数据已成为企业最核心的资产。全球超半数财富 500 强企业选择群晖(Synology)作为数据管理伙伴,其企业级 NAS 解决方案凭借 DSM 操作系统的生态优势、硬件与软件的深度协同,以及覆盖全场景的产品…

C++访问限定符private、public、protected的使用场景

C 访问控制关键字:public、private、protected 在C中,public、private和protected是访问控制关键字,用于实现面向对象编程的封装特性,控制类成员的访问权限。 访问控制关键字的使用场景 1. public(公有成员&#xff09…

CKA08--PVC

Task mariadb namespace 中的 MariaDB Deployment 被误删除。请恢复该 Deployment 并确保数据持久性。 请按照以下步骤: 如下规格在 mariadb namespace 中创建名为 mariadb 的 PersistentVolumeClaim (PVC): 访问模式为 ReadWriteOnce 存储为 250Mi 集群…

Freertos系列(调度机制与创建任务)

如果不想看的可以直接使用git把我的代码下载出来,里面工程挺全的,后期会慢慢的补注释之类的 码云地址:stm32学习笔记: stm32学习笔记源码 如果不会使用git快速下载可以选择直接下载压缩包或者去看看git的使用 Git入门教程-CSDN博客 一 调…