首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Spring Boot `@Service` 互相调用全攻略:`@Autowired` vs `@Resource`

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

作者头像
井九
发布2025-10-31 08:32:41
发布2025-10-31 08:32:41
2070
举报
文章被收录于专栏:四楼没电梯四楼没电梯

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
代码语言:javascript
复制
@Service
public class UserService {
    public String getUserName(Long id) {
        return "User-" + id;
    }
}

@Service
public class OrderService {
    private final UserService userService;

    // 构造器注入(推荐 ✅)
    @Autowired
    public 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
代码语言:javascript
复制
@Service
public class UserService {
    public String getUserName(Long id) {
        return "User-" + id;
    }
}

@Service
public class OrderService {
    @Resource
    private UserService userService; // 按字段名 userService 找 Bean

    public void createOrder(Long userId) {
        System.out.println("订单用户: " + userService.getUserName(userId));
    }
}
3.3 多实现类场景
代码语言:javascript
复制
@Service("vipUserService")
public class VipUserService extends UserService {
    @Override
    public 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 互相依赖

代码语言:javascript
复制
@Service
public class AService {
    @Autowired
    private BService bService;

    public void a() {
        System.out.println("A 调用");
        bService.b();
    }
}

@Service
public class BService {
    @Autowired
    private AService aService;

    public void b() {
        System.out.println("B 调用");
        aService.a();
    }
}

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

4.1 循环调用的可视化

4.2 解决方法
  • 重构代码(最佳 ✅):抽出公共逻辑放到 CService,避免直接互调。
  • 延迟注入(权宜之计):在其中一个依赖上加 @Lazy
代码语言:javascript
复制
@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可视化客户端工具

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-09-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Spring Boot @Service 互相调用全攻略:@Autowired vs @Resource
    • 1. 基础:@Service 是什么?
    • 2. @Autowired:Spring 派来的助手
      • 2.1 特点
      • 2.2 Demo
    • 3. @Resource:JDK 官方背书
      • 3.1 特点
      • 3.2 Demo
      • 3.3 多实现类场景
    • 4. 循环依赖问题
      • 4.1 循环调用的可视化
      • 4.2 解决方法
    • 5. 总结:到底用哪个?
    • 6. 最佳实践建议
    • 实用小工具
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档