# 脚手架 **Repository Path**: weizuxiao911/framework ## Basic Information - **Project Name**: 脚手架 - **Description**: No description available - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2026-04-18 - **Last Updated**: 2026-04-22 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Framework DDD 脚手架 基于 DDD(领域驱动设计)+ Spring Boot 3.3 的分层架构脚手架。 ## 模块结构 ```mermaid graph TB subgraph Bootstrap["bootstrap
启动入口"] App["BootstrapApplication"] end subgraph Interfaces["interfaces
接口层"] Controller["Controller"] ExceptionAdvice["GlobalExceptionAdvice"] PBACAspect["PBACAspect"] end subgraph Application["application
应用层"] AppService["AppService"] DTO["Command / Query / Response"] end subgraph Domain["domain
领域层"] Aggregate["AggregateRoot"] DomainService["DomainService"] Repository["Repository 接口"] DomainEvent["DomainEvent"] end subgraph Common["common
共享内核"] Base["AggregateRoot / BaseRepository"] R["R<T>"] EventBase["DomainEvent / DomainEventPublisher"] PBAC["PBAC 模型 / 注解"] end subgraph Infrastructure["infrastructure
基础设施层"] RepoImpl["RepositoryImpl"] JPA["JPA Entity"] Feign["Feign Client"] Kafka["Kafka Producer / Consumer"] EventDispatcher["EventDispatcher"] end Bootstrap --> Interfaces Bootstrap --> Infrastructure Interfaces --> Application Application --> Domain Infrastructure --> Domain Domain --> Common Infrastructure --> Common ``` ## 分层依赖规则 ```mermaid graph LR bootstrap --> interfaces bootstrap --> infrastructure interfaces --> application application --> domain infrastructure --> domain domain --> common infrastructure --> common linkStyle 0,1 stroke:#333 linkStyle 2 stroke:#333 linkStyle 3,4 stroke:#333 linkStyle 5,6 stroke:#999 ``` - common 不依赖任何模块和框架(纯 Java + Lombok) - domain 不依赖 infrastructure、interfaces - application 不依赖 infrastructure、interfaces - infrastructure 依赖 domain 和 common - interfaces 依赖 application 和 common - bootstrap 聚合所有模块 --- ## 各层开发规范 ### common 层 **定位**:共享内核,跨层复用的基础类、接口和注解。 **依赖约束**: - 零框架依赖,不引入 Spring、JPA 等 - 仅使用 Java 标准库 + Lombok + jackson-annotations **包结构**: | 包 | 职责 | |---|---| | `base/` | `AggregateRoot`, `BaseRepository` | | `dto/` | `R` 统一响应体 | | `event/` | `DomainEvent`, `DomainEventPublisher`, `@OnEvent` | | `exception/` | `DomainException` | | `context/` | `AppContext`, `UserContext` | | `pagination/` | `PageQuery`, `PageResult` | | `annotation/` | `@RequirePolicy`, `@RequirePermission` | | `pbac/` | PBAC 领域模型、服务接口、异常 | ### domain 层 **定位**:纯业务逻辑,定义领域模型和业务规则。 **开发规则**: - 实体继承 `AggregateRoot`,通过 `registerEvent()` 注册领域事件 - 值对象使用 Java record 或不可变类 - 仓储定义为接口(`interface XxxRepository`),实现在 infrastructure 层 - 领域服务定义为接口,default 方法实现通用逻辑 - 不依赖任何框架 **示例**: ```java public class User extends AggregateRoot { public static User create(String username, String email) { User user = new User(); // ... 设置属性 user.registerEvent(new UserCreatedEvent(user.id.value(), username)); return user; } } ``` ### application 层 **定位**:用例编排,协调领域对象完成业务流程。 **开发规则**: - 应用服务(`XxxAppService`)注入领域仓储和领域服务 - 接收 Command/Query DTO,调用领域对象,返回 Response DTO - 通过 `DomainEventPublisher` 发布领域事件 - 不直接操作数据源 ### infrastructure 层 **定位**:技术实现,提供仓储、外部服务、消息队列等具体实现。 **开发规则**: - JPA 实体继承 `BaseEntity`,使用 `@Entity` + `@Table(name = "t_xxx")` - Entity ↔ Domain 转换:`toDomain()` / `fromDomain()` - 仓储实现使用 `UserJpaRepository extends JpaRepository` - Feign 客户端定义 `@FeignClient` + FallbackFactory - 事件处理:`EventDispatcher`(本地)、`KafkaEventConsumer`(跨服务) - 自动配置类放 `META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports` ### interfaces 层 **定位**:HTTP 入口,请求转换和响应包装。 **开发规则**: - Controller 使用 `@RestController` + `@RequestMapping` - 返回值由 `ResponseBodyWrapper` 自动包装为 `R` - 权限控制使用 `@RequirePolicy` 或 `@RequirePermission` - 全局异常处理在 `GlobalExceptionAdvice` - 使用 `@Operation` (SpringDoc) 生成 API 文档 ### bootstrap 层 **定位**:启动入口,最轻量的模块。 **开发规则**: - 启动类加 `@SpringBootApplication` + `@EnableFeignClients` - 只依赖其他模块,不包含业务代码 - 配置文件 `application.yml` 管理所有环境配置 --- ## 核心机制 ### 领域事件 ```mermaid sequenceDiagram participant Agg as 聚合根 participant Pub as DomainEventPublisherImpl participant Local as ApplicationEventPublisher participant Kafka as KafkaTemplate participant ED as EventDispatcher participant Handler as @OnEvent 处理器 participant Consumer as KafkaEventConsumer Agg->>Pub: registerEvent() Pub->>Local: publishEvent(DomainEvent) Local->>ED: @EventListener dispatch() ED->>Handler: 按事件类型路由 Pub->>Kafka: send("domain.{EventType}", JSON) Kafka-->>Consumer: @KafkaListener 消费 Consumer->>ED: dispatchByTypeName() ED->>Handler: 按事件名称路由 ``` - 本地事件:`@OnEvent(XxxEvent.class)` 注解处理方法 - Kafka 事件:纯 JSON 序列化,不依赖 Java 类 ### PBAC 权限控制 ```mermaid sequenceDiagram participant GW as Gateway participant AOP as PBACAspect participant SpEL as SpEL 解析器 participant Svc as PBACServiceImpl participant Ctrl as Controller GW->>AOP: 透传请求(x-user-id, x-tenant-id, x-tenant-permissions) AOP->>Svc: parseUserContext(headers) Svc-->>AOP: UserPermissionContext AOP->>SpEL: 解析 permissionCode SpEL-->>AOP: 所需权限码(如 USER:DELETE) AOP->>Svc: evaluate(context) Svc-->>AOP: EvaluationResult alt 权限通过 AOP->>Ctrl: 放行执行 Ctrl-->>GW: 业务响应 else 权限拒绝 AOP-->>GW: 403 ACCESS_DENIED end ``` Gateway 透传 Headers: | Header | 说明 | 示例 | |--------|------|------| | x-user-id | 用户ID | 123 | | x-tenant-id | 当前租户ID | 1 | | x-accessible-tenants | 可访问租户列表 | 1,2,3 | | x-tenant-permissions | 按租户分组权限(JSON) | {"1":["USER:VIEW"]} | 使用方式: ```java // 固定权限码 @RequirePolicy(permissionCode = "USER:DELETE") // SpEL 动态权限码 @RequirePolicy(permissionCode = "#resourceType + ':VIEW'") // RBAC 风格 @RequirePermission(resource = "USER", resourceValue = "#userId", action = "READ") ``` 权限拒绝返回: ```json {"code":"ACCESS_DENIED","message":"Access denied: required permission [USER:DELETE] not found"} ``` ### 统一响应格式 ```java R.ok(data) // {"code":"0","data":...} R.fail("错误信息") // {"code":"-1","message":"错误信息"} R.fail(code, msg) // {"code":"xxx","message":"xxx"} ``` `@JsonInclude(NON_NULL)` 自动忽略 null 字段。 --- ## 技术栈 | 技术 | 版本 | |------|------| | Java | 17 | | Spring Boot | 3.3.2 | | Spring Cloud OpenFeign | - | | Spring Kafka | - | | JPA / Hibernate | - | | MySQL | 8.x | | Redis | - | | Lombok | - | | Jackson | - | | SpringDoc + Knife4j | - | | JaCoCo | 0.8.11 | ## 快速开始 1. `mvn clean install -Djacoco.skip=true` 2. 配置 MySQL、Redis、Kafka 连接 3. 执行 `infrastructure/ddl.sql` 建表 4. 启动 `BootstrapApplication` 5. 访问 API 文档:`http://localhost:8080/doc.html`