重构Service类实现,将QueryService泛型参数调整为VO类型,确保缓存VO对象而非实体。优化关联实体处理逻辑,减少重复代码。修改findById方法返回VO对象,新增getById方法获取实体。更新相关调用点以适配新接口。 调整WebSocket处理、控制器及Service实现,确保数据类型一致性。完善文档记录重构过程及发现的问题。为后续优化提供基础架构支持。
9.5 KiB
9.5 KiB
Server模块Service缓存调整为Vo对象 - DESIGN文档
1. 整体架构图
flowchart TD
subgraph Client层
Client["JavaFX客户端"]
end
subgraph 表示层
WS["WebSocketServerHandler"]
WSCB["WebSocketServerCallbackManager"]
WSCT["WebSocketServerTaskManager"]
Controller["RESTful Controller"]
end
subgraph 业务层
Service["Service类
(@CacheConfig注解)"]
IES["IEntityService接口"]
QS["QueryService接口"]
VS["VoableService接口"]
end
subgraph 数据访问层
Repository["JPA Repository"]
end
subgraph 数据存储层
MySQL["MySQL数据库"]
Redis["Redis缓存"]
end
Client -->|WebSocket| WS
WS -->|处理会话| WSCT
WS -->|处理消息| WSCB
WSCB -->|动态调用| Service
Controller -->|调用| Service
Service -->|实现| IES
Service -->|实现| QS
Service -->|实现| VS
Service -->|CRUD操作| Repository
Repository -->|持久化| MySQL
Service -->|缓存操作| Redis
2. 分层设计和核心组件
2.1 分层设计
系统采用经典的三层架构,每层职责明确:
-
数据存储层:
- MySQL数据库:存储系统的持久化数据
- Redis缓存:存储VO对象缓存,提高系统性能
-
数据访问层:
- JPA Repository接口:提供对数据库的访问操作
- 主要职责:执行SQL查询,管理实体对象的生命周期
-
业务层:
- Service类:实现业务逻辑,管理缓存
- 核心接口:IEntityService、QueryService、VoableService
- 主要职责:处理业务规则,管理实体与VO的转换,缓存管理
-
表示层:
- WebSocket服务:处理客户端WebSocket连接和消息
- RESTful Controller:处理HTTP请求
- 主要职责:接收和响应客户端请求,调用业务层服务
2.2 核心组件
2.2.1 Service层组件
-
IEntityService接口:
- 泛型参数:T(实体类类型)
- 核心方法:getById、findAll、save、delete
- 职责:提供对实体类的基本CRUD操作
-
QueryService接口:
- 泛型参数:Vo(VO类类型)
- 核心方法:findById、findAll、count
- 职责:提供基于JSON参数的查询功能,返回VO对象
-
VoableService接口:
- 泛型参数:M(实体类类型)、Vo(VO类类型)
- 核心方法:updateByVo
- 职责:提供将VO对象的属性更新到实体对象的功能
-
Service实现类:
- 特点:实现多个接口,使用@CacheConfig等注解配置缓存
- 职责:实现业务逻辑,管理缓存
2.2.2 WebSocket组件
-
WebSocketServerHandler:
- 职责:管理WebSocket会话,处理连接的建立和关闭
- 依赖:WebSocketServerTaskManager、WebSocketServerCallbackManager
-
WebSocketServerTaskManager:
- 职责:加载和管理WebSocket任务类,处理会话任务
-
WebSocketServerCallbackManager:
- 职责:处理客户端发送的消息,调用相应的Service方法
- 特点:通过反射机制动态调用Service方法
3. 模块依赖关系图
flowchart TD
subgraph WebSocket模块
WSH[WebSocketServerHandler]
WSTM[WebSocketServerTaskManager]
WSCM[WebSocketServerCallbackManager]
end
subgraph Service接口模块
IES[IEntityService接口]
QS[QueryService接口]
VS[VoableService接口]
end
subgraph Service实现模块
SImpl[Service实现类]
end
subgraph 数据访问模块
Repo[JPA Repository]
end
subgraph 缓存模块
Redis[Redis缓存]
end
WSH --> WSTM
WSH --> WSCM
WSCM --> SImpl
SImpl --> IES
SImpl --> QS
SImpl --> VS
SImpl --> Repo
SImpl --> Redis
4. 接口契约定义
4.1 IEntityService接口
public interface IEntityService<T> {
/**
* 根据ID获取实体对象
* @param id 实体ID
* @return 实体对象
* 注意:有关联实体时不能使用@Cacheable注解
*/
T getById(Integer id);
/**
* 根据条件查询实体对象列表
* @param spec 查询条件
* @param pageable 分页参数
* @return 分页结果
*/
Page<T> findAll(Specification<T> spec, Pageable pageable);
/**
* 根据搜索文本构建查询条件
* @param searchText 搜索文本
* @return 查询条件
*/
Specification<T> getSpecification(String searchText);
/**
* 根据搜索文本搜索实体对象
* @param searchText 搜索文本
* @return 实体对象列表
*/
default List<T> search(String searchText);
/**
* 删除实体对象
* @param entity 实体对象
*/
void delete(T entity);
/**
* 保存实体对象
* @param entity 实体对象
* @return 保存后的实体对象
*/
T save(T entity);
}
4.2 QueryService接口
public interface QueryService<Vo> {
/**
* 根据ID获取VO对象
* @param id 实体ID
* @return VO对象
*/
Vo findById(Integer id);
/**
* 根据JSON参数查询VO对象列表
* @param paramsNode JSON参数
* @param pageable 分页参数
* @return 分页结果
*/
Page<Vo> findAll(JsonNode paramsNode, Pageable pageable);
/**
* 根据JSON参数统计数量
* @param paramsNode JSON参数
* @return 数量
*/
default long count(JsonNode paramsNode);
}
4.3 VoableService接口
public interface VoableService<M, Vo> {
/**
* 将VO对象的属性更新到实体对象
* @param model 实体对象
* @param vo VO对象
*/
void updateByVo(M model, Vo vo);
}
4.4 WebSocketServerCallbackManager关键方法
public class WebSocketServerCallbackManager {
/**
* 处理findAll方法调用
*/
private Object invokerFindAllMethod(String serviceName, String methodName, JsonNode paramsNode) {
// 实现逻辑
}
/**
* 处理findById方法调用
*/
private Object invokerFindByIdMethod(String serviceName, String methodName, JsonNode paramsNode) {
// 实现逻辑
}
/**
* 处理save方法调用
*/
private Object invokerSaveMethod(String serviceName, String methodName, JsonNode paramsNode) {
// 实现逻辑
}
/**
* 处理delete方法调用
*/
private Object invokerDeleteMethod(String serviceName, String methodName, JsonNode paramsNode) {
// 实现逻辑
}
/**
* 创建新实体对象
*/
private Object createNewEntity(String serviceName, JsonNode paramsNode) {
// 实现逻辑
}
}
5. 数据流向图
5.1 查询数据流程
flowchart TD
Client[客户端] -->|发送查询请求| WS[WebSocketServerHandler]
WS -->|处理请求| WSCB[WebSocketServerCallbackManager]
WSCB -->|动态调用| Service[Service实现类]
Service -->|查询缓存| Redis[Redis缓存]
Redis -->|命中缓存| Service
Service -->|未命中缓存| Repo[JPA Repository]
Repo -->|查询数据库| MySQL[MySQL数据库]
MySQL -->|返回实体| Repo
Repo -->|返回实体| Service
Service -->|实体转VO| Service
Service -->|缓存VO| Redis
Service -->|返回VO| WSCB
WSCB -->|返回结果| WS
WS -->|发送响应| Client
5.2 更新数据流程
flowchart TD
Client[客户端] -->|发送更新请求| WS[WebSocketServerHandler]
WS -->|处理请求| WSCB[WebSocketServerCallbackManager]
WSCB -->|动态调用| Service[Service实现类]
Service -->|清理缓存| Redis[Redis缓存]
Service -->|调用updateByVo| Service
Service -->|保存实体| Repo[JPA Repository]
Repo -->|更新数据库| MySQL[MySQL数据库]
MySQL -->|返回结果| Repo
Repo -->|返回实体| Service
Service -->|实体转VO| Service
Service -->|缓存VO| Redis
Service -->|返回VO| WSCB
WSCB -->|返回结果| WS
WS -->|发送响应| Client
6. 异常处理策略
6.1 全局异常处理
- 使用@ControllerAdvice注解定义全局异常处理器
- 处理常见的异常类型,如数据不存在、参数错误等
- 返回统一的错误响应格式
6.2 业务层异常处理
- Service类中捕获并处理业务逻辑异常
- 向上层抛出经过包装的业务异常
- 记录异常日志
6.3 WebSocket异常处理
- WebSocketServerHandler中捕获并处理WebSocket相关异常
- 关闭异常会话,避免影响其他会话
- 记录异常日志
6.4 缓存异常处理
- 捕获并处理Redis相关异常
- 当缓存不可用时,降级为直接查询数据库
- 记录异常日志,便于问题排查
7. 关键设计决策
7.1 缓存键设计
采用{cacheName}:{entityType}:{id}格式的缓存键,其中:
cacheName:通过@CacheConfig指定的缓存名称entityType:实体类的简单名称id:实体的ID值
7.2 缓存值转换
- 在Service类的findById、findAll等方法中,先查询实体对象,然后转换为Vo对象
- 将转换后的Vo对象存入缓存
- 确保存入缓存的Vo对象是可序列化的
7.3 关联实体处理
- 在updateByVo方法中添加实体匹配检查逻辑
- 使用getById方法获取关联实体,避免直接使用findById
- 对于为null的关联ID,不执行查询操作
7.4 缓存清理策略
- 在save、delete等修改数据的方法中,使用@CacheEvict或@Caching注解清理相关缓存
- 确保缓存与数据库数据的一致性