Skip to content

后端分层约定

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业务名 + ControllerSysUserController
Service 接口业务名 + ServiceSysUserService
Service 实现业务名 + ServiceImplSysUserServiceImpl
Mapper业务名 + MapperSysUserMapper
Entity业务名 + EntitySysUserEntity
DTO业务名 + DTOSysUserDTO
VO业务名 + VOSysUserVO

循环依赖禁止

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 中。原因:DataScopeInterceptormapperMethod 精确匹配改写 SQL。

例外:单表 selectByIdinsertupdateByIddeleteById 等 MyBatis-Plus 内置方法允许直接调用。

Forge Admin — 基于 Vue3 + Spring Boot 的企业级后台管理框架