小工具 · 规范库 · 后端代码规范(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等。