docs: 精简 README 和 openspec 配置,添加 AGENTS.md
This commit is contained in:
349
README.md
349
README.md
@@ -1,260 +1,181 @@
|
|||||||
# Spring Boot Service Template
|
# Spring Boot Service Template
|
||||||
|
|
||||||
微服务快速开发能力模板,提供标准化的能力模块,帮助开发者快速构建 Spring Boot 微服务应用。
|
微服务快速开发能力模板,v1.1.0-SNAPSHOT。Java 17, Spring Boot 4.0.0, Spring Cloud 2025.1.0。
|
||||||
|
|
||||||
**当前版本**: 1.1.0-SNAPSHOT
|
GroupId: `com.lanyuanxiaoyao`,根包: `com.lanyuanxiaoyao.service.template`。
|
||||||
|
|
||||||
## 1. 项目概述
|
## 模块
|
||||||
|
|
||||||
Spring Boot Service Template 是一个能力模块化的微服务开发模板。每个能力模块封装特定领域的通用功能,开发者只需引入依赖、实现少量代码即可获得完整的业务能力。
|
|
||||||
|
|
||||||
**核心价值**:
|
|
||||||
- 能力模块化:每个模块独立可用,按需引入
|
|
||||||
- 零样板代码:通用逻辑已封装,专注业务实现
|
|
||||||
- 多实现支持:同一能力支持多种技术实现,灵活选择
|
|
||||||
|
|
||||||
## 2. 架构
|
|
||||||
|
|
||||||
```
|
```
|
||||||
┌─────────────────────────────────────────────────────────────────────┐
|
spring-boot-service-template/ (根 POM, packaging=pom)
|
||||||
│ Spring Boot Service Template │
|
├── spring-boot-service-template-common/ (jar — 通用工具)
|
||||||
├─────────────────────────────────────────────────────────────────────┤
|
└── spring-boot-service-template-database/ (jar — JPA 数据库能力)
|
||||||
│ │
|
|
||||||
│ ┌──────────────────────────────────────────────────────────────┐ │
|
|
||||||
│ │ 能力模块 (Capability) │ │
|
|
||||||
│ │ │ │
|
|
||||||
│ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │
|
|
||||||
│ │ │ database │ │ user │ │ payment │ ... │ │
|
|
||||||
│ │ │ ✅ 已实现 │ │ 🔜 规划中 │ │ 🔜 规划中 │ │ │
|
|
||||||
│ │ └──────┬──────┘ └─────────────┘ └─────────────┘ │ │
|
|
||||||
│ │ │ │ │
|
|
||||||
│ │ ▼ │ │
|
|
||||||
│ │ ┌─────────────────────────────────────────────┐ │ │
|
|
||||||
│ │ │ jpa │ eq │ xbatis (实现) │ │ │
|
|
||||||
│ │ └─────────────────────────────────────────────┘ │ │
|
|
||||||
│ └──────────────────────────────────────────────────────────────┘ │
|
|
||||||
│ │
|
|
||||||
│ ┌──────────────────────────────────────────────────────────────┐ │
|
|
||||||
│ │ 通用基础 (Common) │ │
|
|
||||||
│ │ │ │
|
|
||||||
│ │ ObjectHelper (对象工具) │ SnowflakeHelper (ID生成) │ │
|
|
||||||
│ └──────────────────────────────────────────────────────────────┘ │
|
|
||||||
│ │
|
|
||||||
└─────────────────────────────────────────────────────────────────────┘
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**模块依赖关系**:
|
模块命名规则: `spring-boot-service-template-{capability}[-{impl}]`
|
||||||
|
|
||||||
|
## 包结构
|
||||||
|
|
||||||
```
|
```
|
||||||
┌─────────────┐
|
com.lanyuanxiaoyao.service.template.{module}/
|
||||||
│ 应用 │
|
configuration/ # @Configuration(用 configuration 不用 config)
|
||||||
└──────┬──────┘
|
controller/ # REST 控制器 + 接口
|
||||||
│
|
entity/ # JPA 实体、Query、GlobalResponse 等数据对象
|
||||||
▼
|
exception/ # 自定义异常(用 exception 不用 exceptions)
|
||||||
┌─────────────────┐ ┌───────────────────┐
|
helper/ # 工具类(用 helper 不用 util/utils)
|
||||||
│ capability-common│────▶│ capability-impl │
|
repository/ # Spring Data 仓库
|
||||||
│ (接口定义) │ │ (jpa/eq/xbatis) │
|
service/ # 业务服务
|
||||||
└───────┬─────────┘ └───────────────────┘
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
┌─────────────┐
|
|
||||||
│ common │
|
|
||||||
│ (通用工具) │
|
|
||||||
└─────────────┘
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## 3. 通用规范
|
无独立 DTO/VO 包,DTO 作为 Controller 内部 record。
|
||||||
|
|
||||||
### 3.1 模块命名
|
## database 模块
|
||||||
|
|
||||||
| 模块类型 | 命名格式 | 示例 |
|
单表 CRUD → REST 接口的快速实现框架。基于 JPA + Fenix + QueryDSL + MapStruct。
|
||||||
|---------|---------|------|
|
|
||||||
| 能力模块 | `spring-boot-service-template-{capability}` | database |
|
|
||||||
| 通用定义 | `spring-boot-service-template-{capability}-common` | database-common |
|
|
||||||
| 具体实现 | `spring-boot-service-template-{capability}-{impl}` | database-jpa |
|
|
||||||
| 通用基础 | `spring-boot-service-template-common` | common |
|
|
||||||
|
|
||||||
### 3.2 依赖原则
|
### 实体继承
|
||||||
|
|
||||||
- **common 模块**:与业务无关的工具类,不依赖任何能力模块
|
```
|
||||||
- **capability-common**:定义接口和通用实体,不依赖具体实现技术
|
IdOnlyEntity (id: Long, @SnowflakeId) ← @MappedSuperclass
|
||||||
- **最小化第三方依赖**:优先使用 JDK 和 Spring 内置能力
|
↑
|
||||||
|
SimpleEntity (+ createdTime: LocalDateTime, ← @MappedSuperclass
|
||||||
### 3.3 响应格式
|
modifiedTime: LocalDateTime)
|
||||||
|
↑
|
||||||
所有 API 使用统一的 `GlobalResponse<T>` 格式:
|
业务实体 (具体 @Entity)
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"status": 0,
|
|
||||||
"message": "OK",
|
|
||||||
"data": { ... }
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
| 字段 | 说明 |
|
- ID: Long,雪花算法,字段标 `@SnowflakeId`(自定义注解)
|
||||||
|-----|------|
|
- 时间字段: `@CreatedDate`/`@LastModifiedDate`,JPA `AuditingEntityListener` 自动填充
|
||||||
| status | 状态码:0=成功,500=错误 |
|
- 列注释: `@Column(comment = "...")`
|
||||||
| message | 描述信息 |
|
- 物理命名: `PhysicalNamingStrategySnakeCaseImpl`(camelCase→snake_case)
|
||||||
| data | 业务数据 |
|
- 保存: Fenix `saveOrUpdateByNotNullProperties()`,自动 INSERT/UPDATE,仅更新非 null 字段
|
||||||
|
|
||||||
列表数据封装:
|
### Repository
|
||||||
|
|
||||||
```json
|
```java
|
||||||
{
|
@NoRepositoryBean
|
||||||
"status": 0,
|
public interface SimpleRepository<E> extends
|
||||||
"message": "OK",
|
FenixJpaRepository<E, Long>,
|
||||||
"data": {
|
FenixJpaSpecificationExecutor<E>,
|
||||||
"items": [...],
|
ListQueryByExampleExecutor<E>,
|
||||||
"total": 100
|
ListQuerydslPredicateExecutor<E> {}
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3.4 代码风格
|
业务 Repository 直接继承: `interface EmployeeRepository extends SimpleRepository<Employee> {}`
|
||||||
|
|
||||||
- **接口与实现分离**:接口定义在 `*-common`,实现在具体模块
|
无 XML Mapper,无自定义 SQL,查询通过 JPA Criteria / Fenix / QueryDSL 动态构建。
|
||||||
- **空值检查**:使用 `ObjectHelper.isNull/isNotNull/isEmpty/isNotEmpty`
|
|
||||||
- **异常定义**:继承 `RuntimeException`,构造器接收业务参数
|
|
||||||
- **注解使用**:`@Getter` / `@Setter` / `@FieldNameConstants` / `@NoArgsConstructor`
|
|
||||||
|
|
||||||
## 4. 能力模块
|
### 接口组合模式
|
||||||
|
|
||||||
### 4.1 database 模块
|
```java
|
||||||
|
SimpleService<ENTITY> extends SaveService<ENTITY>, QueryService<ENTITY>, RemoveService<ENTITY>
|
||||||
单表 CRUD → REST 接口的快速实现,支持三种数据库访问方式。
|
SimpleController<S, L, D> extends SaveController<S>, QueryController<L, D>, RemoveController
|
||||||
|
|
||||||
#### 模块概述
|
|
||||||
|
|
||||||
| 功能 | 说明 |
|
|
||||||
|-----|------|
|
|
||||||
| 保存 | 单条/批量保存,自动判断新增/更新 |
|
|
||||||
| 查询 | 详情查询、列表查询、分页查询、条件查询 |
|
|
||||||
| 删除 | 单条/批量删除 |
|
|
||||||
|
|
||||||
#### 实现方式对比
|
|
||||||
|
|
||||||
| 特性 | JPA | Easy Query | Xbatis |
|
|
||||||
|-----|-----|------------|--------|
|
|
||||||
| 类型安全查询 | ✅ QueryDSL | ✅ Proxy API | ❌ |
|
|
||||||
| 自动审计 | ✅ | ❌ | ❌ |
|
|
||||||
| 逻辑删除 | ❌ | ✅ | ✅ |
|
|
||||||
| 复杂 SQL | 中等 | 中等 | 强 |
|
|
||||||
| 适用场景 | 标准 JPA 项目 | 类型安全 + 逻辑删除 | 复杂查询场景 |
|
|
||||||
|
|
||||||
#### 快速开始
|
|
||||||
|
|
||||||
**1. 添加依赖**
|
|
||||||
|
|
||||||
```xml
|
|
||||||
<!-- JPA 实现 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.lanyuanxiaoyao</groupId>
|
|
||||||
<artifactId>spring-boot-service-template-database-jpa</artifactId>
|
|
||||||
<version>1.1.0-SNAPSHOT</version>
|
|
||||||
</dependency>
|
|
||||||
```
|
```
|
||||||
|
|
||||||
**2. 实现 CRUD 的 5 个步骤**
|
抽象基类: `SimpleServiceSupport`(Service) / `SimpleControllerSupport`(Controller),用 `*Support` 后缀(非 `*Impl`)。
|
||||||
|
|
||||||
参考测试代码:`spring-boot-service-template-database-jpa/src/test/java/.../`
|
Controller 子类必须提供三个 mapper 函数: `saveItemMapper()`, `listItemMapper()`, `detailItemMapper()`
|
||||||
|
|
||||||
| 步骤 | 说明 | 参考文件 |
|
### CRUD 五步
|
||||||
|-----|------|---------|
|
|
||||||
| 1. 创建实体 | 继承 `SimpleEntity` | `entity/Employee.java` |
|
|
||||||
| 2. 创建 Repository | 继承 `SimpleRepository<ENTITY>` | `repository/EmployeeRepository.java` |
|
|
||||||
| 3. 创建 Service | 继承 `SimpleServiceSupport<ENTITY>` | `service/EmployeeService.java` |
|
|
||||||
| 4. 创建 DTO | 定义 SaveItem, ListItem, DetailItem | `controller/EmployeeController.java` |
|
|
||||||
| 5. 创建 Controller | 继承 `SimpleControllerSupport`,实现 3 个 Mapper | `controller/EmployeeController.java` |
|
|
||||||
|
|
||||||
**3. 查询条件语法**
|
1. 创建实体 — 继承 `SimpleEntity`
|
||||||
|
2. 创建 Repository — 继承 `SimpleRepository<Entity>`
|
||||||
|
3. 创建 Service — 继承 `SimpleServiceSupport<Entity>`
|
||||||
|
4. 创建 DTO — 在 Controller 内定义 `SaveItem`/`ListItem`/`DetailItem` record
|
||||||
|
5. 创建 Controller — 继承 `SimpleControllerSupport<Entity, SaveItem, ListItem, DetailItem>`,实现 3 个 mapper
|
||||||
|
|
||||||
```json
|
也可用 `DatabaseHelper.generateBasicFiles()` 自动生成上述脚手架,`@RequestMapping` 路径由实体名 camelCase→snake_case 推导。`DatabaseHelper.generateDDL()` 可从实体类生成 DDL SQL。
|
||||||
{
|
|
||||||
"query": {
|
|
||||||
"equal": { "name": "张三" },
|
|
||||||
"like": { "name": "%张%" },
|
|
||||||
"contain": { "name": "张" },
|
|
||||||
"startWith": { "name": "张" },
|
|
||||||
"endWith": { "name": "三" },
|
|
||||||
"great": { "age": 18 },
|
|
||||||
"less": { "age": 60 },
|
|
||||||
"greatEqual": { "age": 18 },
|
|
||||||
"lessEqual": { "age": 60 },
|
|
||||||
"between": { "age": { "start": 18, "end": 60 } },
|
|
||||||
"inside": { "id": [1, 2, 3] },
|
|
||||||
"notInside": { "id": [1, 2, 3] },
|
|
||||||
"nullEqual": ["deletedTime"],
|
|
||||||
"notNullEqual": ["name"]
|
|
||||||
},
|
|
||||||
"sort": [{ "column": "createdTime", "direction": "DESC" }],
|
|
||||||
"page": { "index": 1, "size": 10 }
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
#### 模块特定规范
|
### API 端点
|
||||||
|
|
||||||
**分层结构**:
|
| 操作 | 方法 | 路径 |
|
||||||
```
|
| --------- | ---- | ---------------- |
|
||||||
Controller (HTTP处理、DTO转换)
|
| 新增/更新 | POST | `/save` |
|
||||||
│
|
| 全部列表 | GET | `/list` |
|
||||||
▼
|
| 条件列表 | POST | `/list` |
|
||||||
Service (业务逻辑、事务管理)
|
| 详情 | GET | `/detail/{id}` |
|
||||||
│
|
| 删除 | GET | `/remove/{id}` |
|
||||||
▼
|
|
||||||
Repository/Mapper (数据访问)
|
|
||||||
│
|
|
||||||
▼
|
|
||||||
Entity (数据模型)
|
|
||||||
```
|
|
||||||
|
|
||||||
**泛型参数**:
|
统一响应: `GlobalResponse<T>(status:Integer, message:String, data:T)`,成功 status=0,失败 status=500。
|
||||||
- `ENTITY` - 实体类型
|
|
||||||
- `SAVE_ITEM` - 保存请求 DTO
|
|
||||||
- `LIST_ITEM` - 列表响应 DTO
|
|
||||||
- `DETAIL_ITEM` - 详情响应 DTO
|
|
||||||
|
|
||||||
**实体继承**:
|
- 列表: `data = ListItem<T>(items:Iterable<T>, total:Long)`
|
||||||
- JPA: `IdOnlyEntity` → `SimpleEntity` → 业务实体
|
- 详情: `data = DetailItem<T>(item:T)`
|
||||||
- EQ/Xbatis: `IdOnlyEntity` → `SimpleEntity` 或 `LogicDeleteEntity`
|
|
||||||
|
|
||||||
### 4.2 user 模块
|
### 查询条件
|
||||||
|
|
||||||
🚧 规划中...
|
查询对象: `Query(Queryable query, List<Sortable> sort, Pageable page)`
|
||||||
|
|
||||||
### 4.3 payment 模块
|
支持: equal/notEqual/like/notLike/contain/notContain/startWith/endWith/great/less/greatEqual/lessEqual/between/notBetween/inside/notInside/nullEqual/notNullEqual/empty/notEmpty
|
||||||
|
|
||||||
🚧 规划中...
|
分页: `Pageable(index, size)`,index 从 1 开始,默认 `(1, 10)`,无排序默认 `createdTime DESC`
|
||||||
|
|
||||||
## 5. 技术栈
|
## 开发规范
|
||||||
|
|
||||||
| 组件 | 版本 |
|
### 命名
|
||||||
|-----|------|
|
|
||||||
| Java | 17 |
|
|
||||||
| Spring Boot | 4.0.0 |
|
|
||||||
| Spring Cloud | 2025.1.0 |
|
|
||||||
| Hibernate | 7.1.8.Final |
|
|
||||||
| QueryDSL | 7.1 |
|
|
||||||
| Easy Query | 3.1.68 |
|
|
||||||
| Xbatis | 1.9.7-spring-boot4 |
|
|
||||||
| Lombok | - |
|
|
||||||
| MapStruct | 1.6.3 |
|
|
||||||
|
|
||||||
## 6. 开发与测试
|
| 类别 | 模式 | 示例 |
|
||||||
|
| --------------- | ---------------------------------------- | ---------------------------------- |
|
||||||
|
| 实体基类 | `*Entity` | `IdOnlyEntity`, `SimpleEntity` |
|
||||||
|
| 业务实体 | 纯名词 | `Employee` |
|
||||||
|
| 控制器接口 | `*Controller` | `SaveController` |
|
||||||
|
| 控制器抽象基类 | `*ControllerSupport` | `SimpleControllerSupport` |
|
||||||
|
| 服务接口 | `*Service` | `SaveService` |
|
||||||
|
| 服务抽象基类 | `*ServiceSupport` | `SimpleServiceSupport` |
|
||||||
|
| 仓库 | `*Repository` | `EmployeeRepository` |
|
||||||
|
| 工具类 | `*Helper` | `ObjectHelper` |
|
||||||
|
| 配置类 | `*Configuration` | `QueryDSLConfiguration` |
|
||||||
|
| 异常 | `*Exception` | `IdNotFoundException` |
|
||||||
|
| 内部 DTO record | `SaveItem`/`ListItem`/`DetailItem` | Controller 内部 |
|
||||||
|
|
||||||
|
- 接口不加 `I` 前缀
|
||||||
|
- 方法: 动词开头 `save()`/`list()`/`detail()`/`remove()`;布尔用 `is`/`has` 前缀
|
||||||
|
- 常量 UPPER_SNAKE_CASE;字段常量用 `@FieldNameConstants` 生成 `{Class}.Fields.{field}`
|
||||||
|
- 泛型: 简单用 `T`/`E`,领域用 `ENTITY`/`SAVE_ITEM`/`LIST_ITEM`/`DETAIL_ITEM`
|
||||||
|
|
||||||
|
### 代码风格
|
||||||
|
|
||||||
|
- 2 空格缩进,K&R 大括号,不用 Tab
|
||||||
|
- Import 排序: `java.*` → `jakarta.*` → 第三方 → `com.lanyuanxiaoyao.*`,不用通配符
|
||||||
|
- 积极使用 Java 17 特性: `record`(DTO) / `var` / `instanceof` 模式匹配 / Text Blocks / `String.formatted()`
|
||||||
|
- JavaDoc 用中文,含 `@param`/`@return`/`@see`,可用 `<p>`/`<h3>`/`<ul>`/`<pre>`
|
||||||
|
- 不写 `//` 行内注释,除非必要
|
||||||
|
|
||||||
|
### 注解
|
||||||
|
|
||||||
|
用:
|
||||||
|
|
||||||
|
- 实体: `@Getter` `@Setter` `@ToString` `@FieldNameConstants`,子类加 `@ToString(callSuper = true)`
|
||||||
|
- 日志: `@Slf4j`
|
||||||
|
- 注入: `@RequiredArgsConstructor(access = AccessLevel.PROTECTED)`(构造器注入)
|
||||||
|
- 事务: 写 `@Transactional(rollbackFor = Throwable.class)`,读 `@Transactional(readOnly = true)`
|
||||||
|
- 实体基类: `@MappedSuperclass` `@EntityListeners(AuditingEntityListener.class)`
|
||||||
|
|
||||||
|
不用:
|
||||||
|
|
||||||
|
- 不用 `@Valid`/`@NotNull` 等校验注解
|
||||||
|
- 不用 Swagger/OpenAPI 注解
|
||||||
|
- 不用 `@Autowired` 字段注入
|
||||||
|
- 不写代码注释(`//`),除非必要
|
||||||
|
|
||||||
|
### 异常
|
||||||
|
|
||||||
|
继承 `RuntimeException`,构造器用 `String.formatted()`。查无数据用 `Optional.orElseThrow(() -> new IdNotFoundException(id))`。无全局 `@ControllerAdvice`。
|
||||||
|
|
||||||
|
### 依赖管理
|
||||||
|
|
||||||
|
版本集中在根 POM `<properties>` + `<dependencyManagement>`,子模块不声明版本。
|
||||||
|
全局继承: `lombok` / `jspecify:1.0.0`
|
||||||
|
核心: `spring-boot-starter-data-jpa` / `fenix-spring-boot-starter:4.0.0` / `querydsl-jpa:7.1` / `mapstruct:1.6.3`
|
||||||
|
database 模块注解处理器: lombok → hibernate-jpamodelgen → querydsl-apt(jpa) → jakarta.persistence-api → mapstruct-processor
|
||||||
|
|
||||||
|
### 通用原则
|
||||||
|
|
||||||
|
- 文档/注释/commit 用中文,代码标识符用英文
|
||||||
|
- 不引入新依赖前先复用已有组件,优先 JDK 和 Spring 内置能力
|
||||||
|
- 构造器注入,不使用 `@Autowired` 字段注入
|
||||||
|
|
||||||
|
### 构建
|
||||||
|
|
||||||
**构建项目**:
|
|
||||||
```bash
|
```bash
|
||||||
mvn clean package
|
mvn clean package
|
||||||
```
|
```
|
||||||
|
|
||||||
**运行测试**:
|
|
||||||
```bash
|
|
||||||
mvn test
|
|
||||||
```
|
|
||||||
|
|
||||||
测试使用 H2 内存数据库,无需额外配置。
|
|
||||||
|
|
||||||
## 7. 文档索引
|
|
||||||
|
|
||||||
- 详细文档:`docs/` 目录
|
|
||||||
- 测试示例:各模块的 `src/test/java/` 目录
|
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
schema: spec-driven
|
schema: spec-driven
|
||||||
|
|
||||||
context: |
|
context: |
|
||||||
- maven管理的java项目,遵循java代码最佳实践规范
|
- **优先阅读README.md**获取项目结构与开发规范,所有代码风格、命名、注解、依赖、API等规范以README为准
|
||||||
- 交流、文档、注释、提交信息使用中文,代码命名使用英文
|
- 新增代码优先复用已有组件、工具、依赖库,不引入新依赖
|
||||||
- 新增代码要遵循原有代码的设计风格和模式,优先考虑复用已有组件、工具、依赖库
|
- 涉及模块结构、API、实体等变更时同步更新README.md
|
||||||
- **优先阅读README.md**,README.md文档是项目的开发文档,记录代码结构和关键开发模式,优先读取获取上下文
|
- Git提交: 仅中文; 格式"类型: 简短描述", 类型: feat/fix/refactor/docs/style/test/chore; 多行描述空行后写详细说明
|
||||||
- 涉及页面/路由/组件/功能模块变更或技术栈调整时,同步更新README.md
|
- 禁止创建git操作task
|
||||||
- Git提交: 仅中文; 格式为"类型: 简短描述",类型可选: feat(新功能)/fix(修复)/refactor(重构)/docs(文档)/style(格式)/test(测试)/chore(构建/工具); 多行描述空行后加详细说明; 禁创建git操作task
|
|
||||||
|
|
||||||
rules:
|
rules:
|
||||||
proposal:
|
proposal:
|
||||||
|
|||||||
Reference in New Issue
Block a user