Skip to content

IoC 与 Service

模块位于 src/core/Service:单例容器 + 装饰器注入,让业务类不必手动 new

核心概念

装饰器 / 类型作用
@Component(name?)注册为 Bean;默认名为类名
@Resource(name)按名称注入到属性
@Mapper(Entity | table, options?)标记 Mapper,混入 BaseMapper CRUD,并可开逻辑删除 / 填充等
@Service(MapperClass)把对应 Mapper 的方法挂到 Service 上,并转发自定义 SQL 方法
MapperTypeMapper 类可继承的空基类,便于类型扩展

Bean 名称默认等于类名,例如:

ts
@Resource('UserService')
userService!: UserService

必须与容器中注册名一致,大小写敏感。

推荐写法

Entity

ts
@TableName('user')
export default class UserEntity {
  @TableId()
  id!: number | string

  @TableField()
  username!: string

  @TableField({ value: 'nick_name' })
  nickName?: string
}

Mapper

ts
@Mapper(UserEntity, { logicDelete: true, fill: true })
export default class UserMapper extends MapperType {}

Service

ts
@Service(UserMapper)
export default class UserService {
  // selectById / selectList / insert / updateById / deleteById 等由框架挂载
}

Controller

ts
@Controller('/api/user')
export default class UserController {
  @Resource('UserService')
  userService!: UserService

  @GetController('/:id')
  @AuthIgnore()
  async detail(@RequestPath() id: string | number) {
    return this.userService.selectById(id)
  }
}

加载顺序

启动时按 entity → mapper → service → controller 扫描,保证注入时依赖已就绪。新增业务时只要把文件放进 src/business/ 对应目录即可被加载。

注意点

  • 不要循环依赖难以解析的 Bean;优先单向:Controller → Service → Mapper
  • @Service(MapperClass) 依赖 Mapper 已用 @Mapper 注册
  • 自定义查询写在 Mapper 上(@Select 等),Service 侧可直接调用同名方法

基于 VitePress 构建