askill
java-architecture-guide

java-architecture-guideSafety 95Repository

Java 业务项目架构原则和编码规范。适用于 Spring Boot + MyBatis-Plus 分层架构项目。在编写/审查/重构 Java 业务代码时主动参考。Use when writing, reviewing, or refactoring Java business code, or when the user mentions architecture, coding standards, layering, or best practices.

0 stars
1.2k downloads
Updated 2/14/2026

Package Files

Loading files...
SKILL.md

Java 业务项目架构指南

分层架构

四层单向调用,禁止反向或跨层依赖:

Controller → Facade → Service → Repository (Mapper)

各层职责

职责注入禁止
ControllerHTTP 入口、参数校验、响应封装Facade注入 Service;包含业务逻辑;添加事务
Facade跨服务编排、事务边界、DTO 组装多个 Service、Converter直接操作 Mapper
Service单一领域业务逻辑、数据操作本域 Mapper、Converter注入其他 Service 或其他域的 Mapper
Repository数据访问(继承 BaseMapper)添加自定义方法(查询在 Service 中构建)

为什么引入 Facade 层

  • 单一职责: Service 层专注自己领域,不承担编排逻辑
  • 降低耦合: Service 不依赖其他 Service,可独立测试
  • 事务清晰: 跨服务事务统一在 Facade 管理
  • 便于定位: 业务编排集中在 Facade,排查问题路径清晰

层间调用铁律

规则 1: Controller 只注入 Facade

// CORRECT
@RestController
@RequiredArgsConstructor
public class PolicyController {
    private final PolicyFacade facade;  // ✅

    @PostMapping
    public ApiResponse<IdResp> create(@Valid @RequestBody PolicyCreateReq req) {
        return ApiResponse.ok(new IdResp(facade.create(req)));
    }
}

// WRONG
public class PolicyController {
    private final PolicyService service;  // ❌ 禁止直接注入 Service
}

规则 2: Service 禁止注入其他 Service

这是最常被违反的规则。跨域数据需求必须上推到 Facade 层。

// WRONG - Service 跨域调用
@Service
public class AlgoServiceServiceImpl {
    private final LlmServiceMapper llmServiceMapper;  // ❌ 注入其他域 Mapper
    private final VideoSourceService videoSourceService;  // ❌ 注入其他 Service
}

// CORRECT - Facade 编排
@Component
@RequiredArgsConstructor
public class AlgoServiceFacade {
    private final AlgoServiceService algoServiceService;  // ✅
    private final LlmServiceService llmServiceService;    // ✅ Facade 注入多个 Service
    
    public AlgoServiceDetail getDetail(Long id) {
        AlgoServiceDetail detail = algoServiceService.getDetail(id);
        if (detail.getLlmServiceId() != null) {
            LlmService llm = llmServiceService.getById(detail.getLlmServiceId());
            detail.setLlmServiceName(llm.getName());
        }
        return detail;
    }
}

规则 3: Mapper 保持空接口

查询逻辑在 Service 中使用 LambdaQueryWrapper 构建,保证类型安全。 禁止 在 Mapper 中新增方法或 Mapper XML 自定义 SQL,复杂条件仍在 Service 使用 Wrapper/apply 构建。

// CORRECT
@Mapper
public interface PolicyMapper extends BaseMapper<AlertPolicy> {
    // 空接口,不添加任何方法
}

// Service 中构建查询
LambdaQueryWrapper<AlertPolicy> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(AlertPolicy::getEnabled, true)
       .orderByDesc(AlertPolicy::getCreateTime);
List<AlertPolicy> list = baseMapper.selectList(wrapper);

// WRONG
@Mapper
public interface PolicyMapper extends BaseMapper<AlertPolicy> {
    @Select("SELECT * FROM alert_policy WHERE enabled = 1")  // ❌
    List<AlertPolicy> findEnabled();
}

事务管理

事务边界

场景事务位置示例
跨服务写操作Facade 层创建任务 + 创建子任务
单服务复杂写操作Service 层批量删除 + 依赖检查
读操作无事务查询列表、查询详情
Controller 层禁止

事务注解标准写法

@Transactional(rollbackFor = Exception.class)
public Long create(TaskCreateReq req) {
    // 业务逻辑
}

事务内禁止

  • 远程调用(HTTP / RPC / 消息发送)
  • 耗时操作(文件 IO、大量计算)
  • @Async 方法调用

异常处理体系

异常层次

RuntimeException
  └── BusinessException (业务异常,含 ErrorCode)
        └── AuthConsoleException (外部系统异常)

各层异常职责

职责
Service抛出 BusinessException(资源不存在、业务规则违反)
Facade不捕获 BusinessException,透传给全局处理器;仅捕获需要补偿的外部调用异常
Controller不处理异常
GlobalExceptionHandler统一捕获,转换为 ApiResponse

错误码分段管理

按业务模块分配错误码范围(如 2xxx 算法服务、3xxx 预警策略),避免冲突。

日志级别规范

场景级别堆栈
业务异常(BusinessException)WARN
参数校验失败WARN
系统异常(未预期)ERROR
关键业务操作(创建/更新/删除)INFO

命名规范

Java 命名

类型规则示例
类名PascalCaseAnalysisTaskService
方法 / 变量camelCasegetTaskById, videoSourceId
常量UPPER_SNAKE_CASEMAX_RETRY_COUNT
包名全小写com.example.service.impl

分层命名

类型命名模式
Controller{Resource}Controller
Facade{Resource}Facade (直接类,无接口)
Service 接口{Resource}Service
Service 实现{Resource}ServiceImpl
Mapper{Resource}Mapper
Entity{Resource}
Converter{Resource}Converter

数据库命名

类型规则示例
表名snake_casealert_policy, video_source_cache
字段名snake_casecreate_time, llm_service_id
外键字段{关联表}_idpolicy_id, task_id
唯一索引uk_{fields}uk_name_version
普通索引idx_{fields}idx_create_time

API 路径

  • 格式: /api/v{version}/{resources} (复数, kebab-case)
  • 示例: /api/v1/llm-services, /api/v1/analysis-tasks

代码质量原则

必须遵守

  • 公共 API 方法必须有 Javadoc
  • 使用 LambdaQueryWrapper 保证类型安全,避免字符串列名
  • 不使用物理外键约束,通过应用层保证数据一致性
  • 所有表使用逻辑删除(deleted 字段)
  • 写操作考虑乐观锁(version_num 字段)
  • 删除前检查依赖关系,防止数据不一致

统一响应格式

所有 API 返回 ApiResponse<T>:

ApiResponse.ok()           // 无数据成功
ApiResponse.ok(data)       // 带数据成功
ApiResponse.error(code, msg)  // 错误

参数校验

  • Request Body: @Valid @RequestBody XxxReq req
  • Path Variable 校验: 类上加 @Validated,参数上加 @NotBlank
  • 校验注解: @NotBlank, @NotNull, @NotEmpty (Jakarta Validation)

常见反模式

反模式为什么不行正确做法
Service 注入其他 Service循环依赖、职责混乱、难以测试跨域编排放 Facade 层
Controller 直接调用 Service跳过 Facade 编排层,业务逻辑散落Controller → Facade → Service
Mapper 中写自定义 SQL丢失类型安全,SQL 散落Service 中用 LambdaQueryWrapper
事务内做 HTTP/RPC 调用长事务、锁争用、调用失败导致回滚事务外调用,或拆分事务
捕获 BusinessException 后吞掉错误被隐藏,调用方无法感知让全局处理器统一处理
Entity 直接作为 API 响应暴露内部结构,难以演化使用 DTO 做 API 契约
不指定 rollbackFor默认只回滚 RuntimeException@Transactional(rollbackFor = Exception.class)

Install

Download ZIP
Requires askill CLI v1.0+

AI Quality Score

82/100Analyzed 2/23/2026

Comprehensive Java architecture guide covering layered architecture (Controller → Facade → Service → Repository), transaction management, exception handling hierarchies, naming conventions, and code quality principles. Features clear CORRECT/WRONG code examples, detailed responsibility tables, and anti-patterns with corrections. While specifically tailored to Spring Boot + MyBatis-Plus projects, the architectural principles are well-structured and broadly applicable. Highly actionable with excellent clarity and safety, though slightly focused on a particular tech stack which limits general reusability.

95
90
70
85
90

Metadata

Licenseunknown
Version-
Updated2/14/2026
Publisherjianyun8023

Tags

apidatabasellm