# 脚手架
**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`