后端分层约定
Forge 后端严格遵循 Controller → Service → Manager → Mapper 四层架构。每一层有明确的职责边界,禁止越层调用或循环依赖。
分层职责
Controller 层 → 接收请求、参数校验、协议转换、调用 Service
↓
Service 层 → 业务编排、事务边界、调用 Manager/Mapper
↓
Manager 层 → [可选] 领域能力、单一职责、可复用
↓
Mapper 层 → 纯数据访问(MyBatis-Plus + XML)各层规则
| 层 | 允许 | 禁止 |
|---|---|---|
| Controller | 参数校验、调用 Service、返回 RespInfo | 写业务逻辑、直接调 Mapper |
| Service | 业务编排、事务控制、调用 Mapper | 互相注入(循环依赖)、写 SQL |
| Manager | 领域能力封装、可被多个 Service 复用 | 直接接收 HTTP 请求 |
| Mapper | 数据库 CRUD、XML 查询 | 写业务逻辑 |
包名规范
每个 plugin 内部统一包结构:
plugin-xxx/
├── controller/ # XxxController
├── service/ # XxxService(接口)
│ └── impl/ # XxxServiceImpl(实现)
├── mapper/ # XxxMapper(接口)
├── entity/ # XxxEntity(数据库映射)
├── dto/ # XxxDTO(请求参数)
├── vo/ # XxxVO(响应数据)
├── constant/ # 常量定义
└── listener/ # 事件监听器类名规范
| 类型 | 命名规则 | 示例 |
|---|---|---|
| Controller | 业务名 + Controller | SysUserController |
| Service 接口 | 业务名 + Service | SysUserService |
| Service 实现 | 业务名 + ServiceImpl | SysUserServiceImpl |
| Mapper | 业务名 + Mapper | SysUserMapper |
| Entity | 业务名 + Entity | SysUserEntity |
| DTO | 业务名 + DTO | SysUserDTO |
| VO | 业务名 + VO | SysUserVO |
循环依赖禁止
Service 之间禁止互相注入。如果两个 Service 需要协调:
java
// 禁止:循环依赖
@Service
public class OrderService {
@Autowired private ProductService productService; // 如果 ProductService 也注入 OrderService → 循环
}
// 正确:跨 Service 协调逻辑提到 Controller 层
@RestController
public class OrderController {
@Autowired private OrderService orderService;
@Autowired private ProductService productService;
@PostMapping("/order")
public RespInfo create(@RequestBody OrderDTO dto) {
productService.checkStock(dto.getProductId()); // 先校验
return RespInfo.success(orderService.create(dto)); // 再执行
}
}SQL 写入位置
查询类 SQL 禁止在 Service 层用 LambdaQueryWrapper 构建,必须写在 Mapper XML 中。原因:DataScopeInterceptor 按 mapperMethod 精确匹配改写 SQL。
例外:单表 selectById、insert、updateById、deleteById 等 MyBatis-Plus 内置方法允许直接调用。
