宇我的小宇宙
小工具 · 规范库 · 后端代码规范(Java / Spring Boot / SQL)

Spring Boot 分层与服务规范

← 返回上一页
rules/10-backend/spring-boot-service.md

Spring Boot 分层与服务规范

适用范围

后端各微服务模块(AppointReg / Bill / MedInsurance / MDM / CommonService / OutPatient 等)。

分层职责(严格遵守)

Controller 层

  • 只做:参数接收、参数校验(@Valid / 手动校验)、调用 Service、组装统一返回体。
  • 不做:业务逻辑、直接操作数据库、跨多个 Service 编排复杂流程(编排放到 Service)。
  • 不要在 Controller 里 new 出业务对象再传下去;用 DTO 接收,Service 内转 Entity。
  • RestController 接口统一前缀,URL 用 kebab-case 或遵循模块既有约定。
// Do
@PostMapping("/register")
public Result<RegVO> register(@Valid @RequestBody RegDTO dto) {
    return Result.success(regService.register(dto));
}

// Don't:Controller 里写业务 + 直接查库
@PostMapping("/register")
public Result register(@RequestBody Map<String,Object> body) {
    String idcard = (String) body.get("idcard");
    // ❌ 没有 DTO、没有校验、Controller 里拼业务、直接调 mapper
}

Service 层

  • 接口在 service,实现在 service.impl,实现类 XxxServiceImpl。
  • 业务逻辑的唯一归属;包含事务边界。
  • 跨表/跨数据源的写操作,事务放在 Service 方法上;注意 @Transactional 在自调用(this 调用)、private 方法、checked exception 默认不回滚等失效场景。
  • Service 之间可以互相注入,但要避免循环依赖。

Mapper / DAO 层

  • 只做:数据访问,执行 SQL,返回 Entity 或 DTO。
  • 不做:业务判断、循环里逐条查询(N+1 问题)、调用 Service。
  • 复杂查询优先单条 SQL + 合理索引;确实需要批量,用 IN 或批量执行。

入参与出参

  • Controller 入参用 DTO(带校验注解 @NotBlank @NotNull @Size 等),不要用 Map/JSONObject 通杀。
  • 出参用 VO,按前端需要裁剪,不要把 Entity 直接序列化出去(暴露内部字段、易引发循环引用)。
  • 统一返回体:遵循模块已有的 Result/ApiResponse 等封装(含 code/message/data),不要新造第二套。

参数校验

  • Bean Validation 注解校验基础规则;业务规则(如"该号源是否可约")在 Service 校验并抛业务异常。
  • 校验失败由全局异常处理器转成统一错误码,不要在 Controller 里 try-catch 后手动拼返回。

事务与一致性

  • 涉及金额、库存(号源)、医保结算等关键写操作,必须显式事务。
  • 跨服务调用(Feign/RPC)不在本地事务范围内,注意最终一致性,不要假设远程成功就万事大吉。
  • 高并发资源(号源、库存)的扣减要走数据库行锁/乐观锁/唯一约束,不要靠"先查后改"判断。

接口幂等

  • 创建类接口(挂号、收费、结算)应考虑幂等,防止重复提交:前端按钮禁用 + 后端幂等 key/唯一约束。

配置

  • 连接信息、第三方密钥走 application.yml + 环境变量/配置中心,禁止硬编码(见 security-anti-leak.md)。
  • 多环境(dev/test/prod)用 profile 区分:application-dev.yml 等。