feat: complete all post-refactor tasks (performance, monitoring, docs, CI/CD)
This commit is contained in:
@@ -0,0 +1,884 @@
|
||||
# 模块架构重构执行计划
|
||||
|
||||
> **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:数据访问对象
|
||||
- repository:repository实现
|
||||
- converter:实体和领域对象转换器
|
||||
|
||||
### manage-common
|
||||
通用工具和配置模块,包含:
|
||||
- 工具类:SnowflakeId等
|
||||
- 通用DTO:PageRequest、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. **测试覆盖**:重构后确保所有测试仍然通过
|
||||
Reference in New Issue
Block a user