Files
gym-manage/gym-manage-api/docs/plans/2026-03-13-module-refactoring.md

885 lines
27 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 模块架构重构执行计划
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
**Goal:** 重构项目模块架构,实现清晰的职责划分和依赖倒置
**Architecture:**
- app模块:只包含启动类、应用级配置和flyway脚本
- sys模块:包含所有业务代码(domain、service、handler等)和业务级配置
- gateway模块:包含路由和限流配置
- db模块:依赖sys模块,实现repository接口
- common模块:提供通用工具类和基础配置
**Tech Stack:** Maven, Spring Boot, Spring WebFlux, Spring Security, R2DBC
---
## 重构目标
### 模块职责划分
| 模块 | 职责 | 内容 |
|-------|--------|------|
| manage-app | 应用启动和配置 | ManageApplication.java、application.yml、flyway脚本、应用级配置(WebFluxConfig、MultipartConfig、OpenApiConfig |
| manage-sys | 业务逻辑 | domain、repository接口、service接口和实现、handler、业务级配置(SecurityConfig、WebSocketConfig |
| manage-gateway | 网关路由和限流 | GatewayApplication.java、路由配置(SystemRouter)、限流配置(RateLimitConfig |
| manage-db | 数据访问实现 | entity、dao、repository实现、converter |
| manage-common | 通用工具和配置 | 工具类、通用DTO、基础配置、全局异常处理(GlobalExceptionHandler |
### 依赖关系
```
manage-gateway → 无依赖(独立模块)
manage-app → manage-sys + manage-db
manage-sys → manage-common
manage-db → manage-sys
manage-common → 无依赖
```
---
## Task 1: 将RateLimitConfig从app模块移到gateway模块
**Files:**
- Create: `manage-gateway/src/main/java/cn/novalon/manage/gateway/config/RateLimitConfig.java`
- Delete: `manage-app/src/main/java/cn/novalon/manage/app/config/RateLimitConfig.java`
**Step 1: 创建gateway模块的config目录**
```bash
mkdir -p manage-gateway/src/main/java/cn/novalon/manage/gateway/config
```
**Step 2: 移动RateLimitConfig.java**
```bash
mv manage-app/src/main/java/cn/novalon/manage/app/config/RateLimitConfig.java \
manage-gateway/src/main/java/cn/novalon/manage/gateway/config/
```
**Step 3: 更新RateLimitConfig.java的包声明**
```java
// 将
package cn.novalon.manage.sys.config;
// 改为
package cn.novalon.manage.gateway.config;
```
**Step 4: 更新gateway模块的pom.xml,添加Resilience4j依赖**
```xml
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-spring-boot3</artifactId>
<version>2.2.0</version>
</dependency>
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-reactor</artifactId>
<version>2.2.0</version>
</dependency>
```
**Step 5: 更新gateway模块的application.yml,添加限流配置**
```yaml
rate:
limit:
limit-for-period: 100
limit-refresh-period: 1s
timeout-duration: 0
```
**Step 6: 提交更改**
```bash
git add manage-gateway/src/main/java/cn/novalon/manage/gateway/config/RateLimitConfig.java
git add manage-gateway/pom.xml
git add manage-gateway/src/main/resources/application.yml
git rm manage-app/src/main/java/cn/novalon/manage/app/config/RateLimitConfig.java
git commit -m "refactor: move RateLimitConfig to gateway module"
```
---
## Task 2: 将SystemRouter从app模块移到gateway模块
**Files:**
- Create: `manage-gateway/src/main/java/cn/novalon/manage/gateway/config/SystemRouter.java`
- Delete: `manage-app/src/main/java/cn/novalon/manage/app/config/SystemRouter.java`
**Step 1: 移动SystemRouter.java**
```bash
mv manage-app/src/main/java/cn/novalon/manage/app/config/SystemRouter.java \
manage-gateway/src/main/java/cn/novalon/manage/gateway/config/
```
**Step 2: 更新SystemRouter.java的包声明**
```java
// 将
package cn.novalon.manage.sys.config;
// 改为
package cn.novalon.manage.gateway.config;
```
**Step 3: 更新GatewayApplication.java,集成SystemRouter**
```java
package cn.novalon.manage.gateway;
import cn.novalon.manage.gateway.config.SystemRouter;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder, SystemRouter systemRouter) {
return systemRouter.buildRoutes(builder);
}
}
```
**Step 4: 更新SystemRouter.java,使用RouteLocatorBuilder**
```java
package cn.novalon.manage.gateway.config;
import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.stereotype.Component;
/**
* 系统路由配置
*
* 文件定义:配置Spring Cloud Gateway的路由规则
* 涉及业务:API路由、负载均衡、服务发现
* 算法:使用Spring Cloud Gateway的路由匹配和转发
*
* @author 张翔
* @date 2026-03-13
*/
@Component
public class SystemRouter {
public RouteLocator buildRoutes(RouteLocatorBuilder builder) {
return builder.routes()
.route("manage-app", r -> r
.path("/api/**")
.uri("http://manage-app:8081"))
.build();
}
}
```
**Step 5: 提交更改**
```bash
git add manage-gateway/src/main/java/cn/novalon/manage/gateway/config/SystemRouter.java
git add manage-gateway/src/main/java/cn/novalon/manage/gateway/GatewayApplication.java
git rm manage-app/src/main/java/cn/novalon/manage/app/config/SystemRouter.java
git commit -m "refactor: move SystemRouter to gateway module"
```
---
## Task 3: 将SecurityConfig从app模块移到sys模块
**Files:**
- Create: `manage-sys/src/main/java/cn/novalon/manage/sys/config/SecurityConfig.java`
- Delete: `manage-app/src/main/java/cn/novalon/manage/app/config/SecurityConfig.java`
**Step 1: 创建sys模块的config目录**
```bash
mkdir -p manage-sys/src/main/java/cn/novalon/manage/sys/config
```
**Step 2: 移动SecurityConfig.java**
```bash
mv manage-app/src/main/java/cn/novalon/manage/app/config/SecurityConfig.java \
manage-sys/src/main/java/cn/novalon/manage/sys/config/
```
**Step 3: 更新SecurityConfig.java的包声明**
```java
// 将
package cn.novalon.manage.sys.config;
// 改为
package cn.novalon.manage.sys.config;
```
**Step 4: 提交更改**
```bash
git add manage-sys/src/main/java/cn/novalon/manage/sys/config/SecurityConfig.java
git rm manage-app/src/main/java/cn/novalon/manage/app/config/SecurityConfig.java
git commit -m "refactor: move SecurityConfig to sys module"
```
---
## Task 4: 将WebSocketConfig从app模块移到sys模块
**Files:**
- Create: `manage-sys/src/main/java/cn/novalon/manage/sys/config/WebSocketConfig.java`
- Delete: `manage-app/src/main/java/cn/novalon/manage/app/config/WebSocketConfig.java`
**Step 1: 移动WebSocketConfig.java**
```bash
mv manage-app/src/main/java/cn/novalon/manage/app/config/WebSocketConfig.java \
manage-sys/src/main/java/cn/novalon/manage/sys/config/
```
**Step 2: 更新WebSocketConfig.java的包声明**
```java
// 将
package cn.novalon.manage.sys.config;
// 改为
package cn.novalon.manage.sys.config;
```
**Step 3: 提交更改**
```bash
git add manage-sys/src/main/java/cn/novalon/manage/sys/config/WebSocketConfig.java
git rm manage-app/src/main/java/cn/novalon/manage/app/config/WebSocketConfig.java
git commit -m "refactor: move WebSocketConfig to sys module"
```
---
## Task 5: 将GlobalExceptionHandler移到common模块并重构
**Files:**
- Create: `manage-common/src/main/java/cn/novalon/manage/common/handler/GlobalExceptionHandler.java`
- Create: `manage-common/src/main/java/cn/novalon/manage/common/handler/ExceptionLogService.java`
- Delete: `manage-app/src/main/java/cn/novalon/manage/app/handler/GlobalExceptionHandler.java`
**Step 1: 创建common模块的handler目录**
```bash
mkdir -p manage-common/src/main/java/cn/novalon/manage/common/handler
```
**Step 2: 创建异常日志服务接口**
```java
package cn.novalon.manage.common.handler;
import reactor.core.publisher.Mono;
/**
* 异常日志服务接口
*
* 文件定义:定义异常日志记录的抽象接口
* 涉及业务:异常日志记录、错误追踪
* 算法:使用响应式编程实现异步日志记录
*
* @author 张翔
* @date 2026-03-13
*/
public interface ExceptionLogService {
Mono<Void> logException(String title, String exceptionName, String exceptionMsg,
String methodName, String ip, String stackTrace);
}
```
**Step 3: 重构GlobalExceptionHandler,移除对sys模块的依赖**
```java
package cn.novalon.manage.common.handler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.server.ResponseStatusException;
import org.springframework.web.server.ServerWebExchange;
import org.springframework.web.server.ServerWebInputException;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 全局异常处理器
*
* 文件定义:统一处理系统中抛出的各种异常,返回标准化的错误响应
* 涉及业务:异常捕获、错误日志记录、错误响应格式化
* 算法:使用@RestControllerAdvice注解实现全局异常拦截
*
* @author 张翔
* @date 2026-03-13
*/
@RestControllerAdvice
public class GlobalExceptionHandler {
private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);
private final ExceptionLogService exceptionLogService;
public GlobalExceptionHandler(ExceptionLogService exceptionLogService) {
this.exceptionLogService = exceptionLogService;
}
@ExceptionHandler(RuntimeException.class)
public ResponseEntity<Map<String, Object>> handleRuntimeException(RuntimeException ex, ServerWebExchange exchange) {
logger.warn("Runtime exception: ", ex);
Map<String, Object> response = new HashMap<>();
if (ex.getMessage() != null && ex.getMessage().contains("not found")) {
response.put("code", HttpStatus.NOT_FOUND.value());
response.put("message", ex.getMessage());
response.put("timestamp", LocalDateTime.now());
return ResponseEntity.status(HttpStatus.NOT_FOUND).body(response);
}
response.put("code", HttpStatus.BAD_REQUEST.value());
response.put("message", ex.getMessage());
response.put("timestamp", LocalDateTime.now());
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(response);
}
@ExceptionHandler(Exception.class)
public ResponseEntity<Map<String, Object>> handleException(Exception ex, ServerWebExchange exchange) {
logger.error("Exception occurred: ", ex);
exceptionLogService.logException(
"System Exception",
ex.getClass().getSimpleName(),
ex.getMessage(),
exchange.getRequest().getPath().value(),
getClientIp(exchange),
getStackTrace(ex)
).subscribe();
Map<String, Object> response = new HashMap<>();
response.put("code", HttpStatus.INTERNAL_SERVER_ERROR.value());
response.put("message", "Internal server error");
response.put("timestamp", LocalDateTime.now());
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body(response);
}
@ExceptionHandler(IllegalArgumentException.class)
public ResponseEntity<Map<String, Object>> handleIllegalArgumentException(IllegalArgumentException ex, ServerWebExchange exchange) {
logger.warn("Illegal argument: ", ex);
Map<String, Object> response = new HashMap<>();
response.put("code", HttpStatus.BAD_REQUEST.value());
response.put("message", ex.getMessage());
response.put("timestamp", LocalDateTime.now());
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(response);
}
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<Map<String, Object>> handleMethodArgumentNotValidException(MethodArgumentNotValidException ex, ServerWebExchange exchange) {
logger.warn("Validation failed: ", ex);
Map<String, Object> response = new HashMap<>();
response.put("code", HttpStatus.BAD_REQUEST.value());
response.put("message", "Validation failed");
response.put("timestamp", LocalDateTime.now());
Map<String, String> fieldErrors = ex.getBindingResult()
.getFieldErrors()
.stream()
.collect(Collectors.toMap(FieldError::getField, FieldError::getDefaultMessage, (e1, e2) -> e1));
response.put("errors", fieldErrors);
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(response);
}
@ExceptionHandler(ServerWebInputException.class)
public ResponseEntity<Map<String, Object>> handleServerWebInputException(ServerWebInputException ex, ServerWebExchange exchange) {
logger.warn("Invalid input: ", ex);
Map<String, Object> response = new HashMap<>();
response.put("code", HttpStatus.BAD_REQUEST.value());
response.put("message", "Invalid input");
response.put("timestamp", LocalDateTime.now());
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(response);
}
@ExceptionHandler(ResponseStatusException.class)
public ResponseEntity<Map<String, Object>> handleResponseStatusException(ResponseStatusException ex, ServerWebExchange exchange) {
logger.warn("Response status exception: ", ex);
Map<String, Object> response = new HashMap<>();
response.put("code", ex.getStatusCode().value());
response.put("message", ex.getReason());
response.put("timestamp", LocalDateTime.now());
return ResponseEntity.status(ex.getStatusCode()).body(response);
}
@ExceptionHandler(DuplicateKeyException.class)
public ResponseEntity<Map<String, Object>> handleDuplicateKeyException(DuplicateKeyException ex, ServerWebExchange exchange) {
logger.warn("Duplicate key: ", ex);
Map<String, Object> response = new HashMap<>();
response.put("code", HttpStatus.CONFLICT.value());
response.put("message", "Duplicate key violation");
response.put("timestamp", LocalDateTime.now());
return ResponseEntity.status(HttpStatus.CONFLICT).body(response);
}
@ExceptionHandler(DataIntegrityViolationException.class)
public ResponseEntity<Map<String, Object>> handleDataIntegrityViolationException(DataIntegrityViolationException ex, ServerWebExchange exchange) {
logger.warn("Data integrity violation: ", ex);
Map<String, Object> response = new HashMap<>();
response.put("code", HttpStatus.CONFLICT.value());
response.put("message", "Data integrity violation");
response.put("timestamp", LocalDateTime.now());
return ResponseEntity.status(HttpStatus.CONFLICT).body(response);
}
private String getClientIp(ServerWebExchange exchange) {
return exchange.getRequest().getHeaders().getFirst("X-Forwarded-For",
exchange.getRequest().getRemoteAddress().getAddress().getHostAddress());
}
private String getStackTrace(Exception ex) {
StringBuilder stackTrace = new StringBuilder();
for (StackTraceElement element : ex.getStackTrace()) {
stackTrace.append(element.toString()).append("\n");
}
return stackTrace.toString();
}
}
```
**Step 4: 移动GlobalExceptionHandler.java**
```bash
mv manage-app/src/main/java/cn/novalon/manage/app/handler/GlobalExceptionHandler.java \
manage-common/src/main/java/cn/novalon/manage/common/handler/
```
**Step 5: 更新GlobalExceptionHandler.java的包声明**
```java
// 将
package cn.novalon.manage.sys.handler;
// 改为
package cn.novalon.manage.common.handler;
```
**Step 6: 在sys模块实现ExceptionLogService接口**
```java
package cn.novalon.manage.sys.handler;
import cn.novalon.manage.common.handler.ExceptionLogService;
import cn.novalon.manage.sys.core.domain.SysExceptionLog;
import cn.novalon.manage.sys.core.service.ISysExceptionLogService;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Mono;
/**
* 异常日志服务实现
*
* 文件定义:实现异常日志记录接口,使用sys模块的异常日志服务
* 涉及业务:异常日志记录、错误追踪
* 算法:使用响应式编程实现异步日志记录
*
* @author 张翔
* @date 2026-03-13
*/
@Service
public class ExceptionLogServiceImpl implements ExceptionLogService {
private final ISysExceptionLogService exceptionLogService;
public ExceptionLogServiceImpl(ISysExceptionLogService exceptionLogService) {
this.exceptionLogService = exceptionLogService;
}
@Override
public Mono<Void> logException(String title, String exceptionName, String exceptionMsg,
String methodName, String ip, String stackTrace) {
SysExceptionLog exceptionLog = new SysExceptionLog();
exceptionLog.setTitle(title);
exceptionLog.setExceptionName(exceptionName);
exceptionLog.setExceptionMsg(exceptionMsg);
exceptionLog.setMethodName(methodName);
exceptionLog.setIp(ip);
exceptionLog.setCreateTime(LocalDateTime.now());
exceptionLog.setStackTrace(stackTrace);
return exceptionLogService.save(exceptionLog).then();
}
}
```
**Step 7: 在sys模块的配置中注册ExceptionLogServiceImpl**
```java
package cn.novalon.manage.sys.config;
import cn.novalon.manage.common.handler.ExceptionLogService;
import cn.novalon.manage.sys.handler.ExceptionLogServiceImpl;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 异常日志配置类
*
* 文件定义:配置异常日志服务的实现
* 涉及业务:异常日志记录、错误追踪
* 算法:使用Spring的依赖注入实现接口和实现的绑定
*
* @author 张翔
* @date 2026-03-13
*/
@Configuration
public class ExceptionLogConfig {
@Bean
public ExceptionLogService exceptionLogService(ExceptionLogServiceImpl exceptionLogServiceImpl) {
return exceptionLogServiceImpl;
}
}
```
**Step 8: 提交更改**
```bash
git add manage-common/src/main/java/cn/novalon/manage/common/handler/GlobalExceptionHandler.java
git add manage-common/src/main/java/cn/novalon/manage/common/handler/ExceptionLogService.java
git add manage-sys/src/main/java/cn/novalon/manage/sys/handler/ExceptionLogServiceImpl.java
git add manage-sys/src/main/java/cn/novalon/manage/sys/config/ExceptionLogConfig.java
git rm manage-app/src/main/java/cn/novalon/manage/app/handler/GlobalExceptionHandler.java
git commit -m "refactor: move GlobalExceptionHandler to common module with dependency inversion"
```
---
## Task 6: 更新app模块的ManageApplication.java
**Files:**
- Modify: `manage-app/src/main/java/cn/novalon/manage/app/ManageApplication.java`
**Step 1: 更新ManageApplication.java的组件扫描配置**
```java
package cn.novalon.manage.app;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.data.r2dbc.repository.config.EnableR2dbcRepositories;
/**
* 管理应用主类
*
* 文件定义:Spring Boot应用启动类,配置组件扫描和功能启用
* 涉及业务:应用启动、组件扫描、功能配置
* 算法:使用Spring Boot自动配置和注解驱动
*
* @author 张翔
* @date 2026-03-13
*/
@SpringBootApplication
@ConfigurationPropertiesScan(basePackages = "cn.novalon.manage")
@ComponentScan(basePackages = {"cn.novalon.manage.sys", "cn.novalon.manage.db"})
@EnableR2dbcRepositories(basePackages = "cn.novalon.manage.db.repository")
public class ManageApplication {
public static void main(String[] args) {
SpringApplication.run(ManageApplication.class, args);
}
}
```
**Step 2: 提交更改**
```bash
git add manage-app/src/main/java/cn/novalon/manage/app/ManageApplication.java
git commit -m "refactor: update ManageApplication component scan configuration"
```
---
## Task 7: 更新app模块的pom.xml
**Files:**
- Modify: `manage-app/pom.xml`
**Step 1: 确保app模块依赖sys和db模块**
```xml
<dependencies>
<dependency>
<groupId>cn.novalon.manage</groupId>
<artifactId>manage-sys</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>cn.novalon.manage</groupId>
<artifactId>manage-db</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>r2dbc-postgresql</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-database-postgresql</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
```
**Step 2: 移除不需要的依赖**
```xml
<!-- 移除以下依赖 -->
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-spring-boot3</artifactId>
<version>2.2.0</version>
</dependency>
<dependency>
<groupId>io.github.resilience4j</groupId>
<artifactId>resilience4j-reactor</artifactId>
<version>2.2.0</version>
</dependency>
```
**Step 3: 提交更改**
```bash
git add manage-app/pom.xml
git commit -m "refactor: update app module dependencies"
```
---
## Task 8: 编译和测试验证
**Files:**
- Test: `manage-app`, `manage-sys`, `manage-db`, `manage-gateway`
**Step 1: 清理并编译所有模块**
```bash
mvn clean compile -DskipTests
```
**Expected:** 所有模块编译成功,无错误
**Step 2: 运行单元测试**
```bash
mvn test
```
**Expected:** 所有测试通过
**Step 3: 启动应用验证**
```bash
cd manage-app
mvn spring-boot:run
```
**Expected:** 应用成功启动,无错误日志
**Step 4: 提交更改**
```bash
git add .
git commit -m "refactor: complete module architecture refactoring"
```
---
## Task 9: 更新文档
**Files:**
- Create: `docs/architecture/module-architecture.md`
**Step 1: 创建模块架构文档**
```markdown
# 模块架构设计
## 模块职责划分
### manage-app
应用启动和配置模块,包含:
- ManageApplication.java:应用启动类
- application.yml:应用配置文件
- flyway脚本:数据库迁移脚本
- 应用级配置:WebFluxConfig、MultipartConfig、OpenApiConfig、GlobalExceptionHandler
### manage-sys
业务逻辑模块,包含:
- domain:领域对象(SysUser、SysRole、SysMenu等)
- repository:数据访问接口
- service:业务逻辑接口和实现
- handler:业务处理器(用户、角色、菜单等)
- 业务级配置:SecurityConfig、WebSocketConfig
- 其他:filter、security、websocket、primitive、command、dto
### manage-gateway
网关模块,包含:
- GatewayApplication.java:网关启动类
- 路由配置:SystemRouter
- 限流配置:RateLimitConfig
### manage-db
数据访问实现模块,包含:
- entity:数据库实体
- dao:数据访问对象
- repositoryrepository实现
- converter:实体和领域对象转换器
### manage-common
通用工具和配置模块,包含:
- 工具类:SnowflakeId等
- 通用DTOPageRequest、PageResponse
- 基础配置:JwtProperties、CacheConfig
## 依赖关系
```
manage-gateway → 无依赖(独立模块)
manage-app → manage-sys + manage-db
manage-sys → manage-common
manage-db → manage-sys
manage-common → 无依赖
```
## 依赖倒置实现
通过manage-app模块的依赖注入,实现依赖倒置:
- sys模块定义repository接口
- db模块实现repository接口
- app模块通过@ComponentScan扫描db模块的repository实现
- app模块通过@EnableR2dbcRepositories启用R2DBC repository
- common模块定义ExceptionLogService接口
- sys模块实现ExceptionLogService接口
- app模块通过配置注册ExceptionLogService实现
```
**Step 2: 提交文档**
```bash
git add docs/architecture/module-architecture.md
git commit -m "docs: add module architecture documentation"
```
---
## 验证清单
### 编译验证
- [ ] manage-common编译成功
- [ ] manage-sys编译成功
- [ ] manage-db编译成功
- [ ] manage-app编译成功
- [ ] manage-gateway编译成功
### 功能验证
- [ ] 应用启动成功
- [ ] 数据库连接正常
- [ ] API访问正常
- [ ] WebSocket连接正常
- [ ] 安全认证正常
- [ ] 限流功能正常
### 依赖验证
- [ ] manage-sys不依赖manage-db
- [ ] manage-db依赖manage-sys
- [ ] manage-app依赖manage-sys和manage-db
- [ ] manage-gateway无依赖
### 测试验证
- [ ] 单元测试全部通过
- [ ] 集成测试全部通过
- [ ] E2E测试全部通过
---
## 回滚计划
如果重构过程中出现问题,可以使用以下命令回滚:
```bash
# 回滚到重构前的状态
git reset --hard <commit-hash-before-refactoring>
# 或者使用git reflog查找之前的提交
git reflog
git reset --hard HEAD@{n}
```
---
## 注意事项
1. **循环依赖**:确保manage-sys不依赖manage-db
2. **包声明**:移动文件后记得更新包声明
3. **import语句**:更新所有import语句以匹配新的包结构
4. **配置文件**:确保application.yml中的配置正确
5. **组件扫描**:确保ManageApplication.java中的@ComponentScan配置正确
6. **测试覆盖**:重构后确保所有测试仍然通过