refactor(model): 重构模型类包结构并优化序列化处理
重构模型类包结构,将模型类按功能模块划分到不同的子包中。优化序列化处理,为VO类添加serialVersionUID并实现Serializable接口。移除部分冗余的serialVersionUID字段,简化模型类代码。同时修复UITools中空值处理的问题,并更新pom版本至0.0.100-SNAPSHOT。 - 将模型类按功能模块划分到ds子包中 - 为VO类添加序列化支持 - 移除冗余的serialVersionUID字段 - 修复UITools空值处理问题 - 更新项目版本号
This commit is contained in:
@@ -1,100 +1,149 @@
|
||||
# Server模块Service缓存调整为Vo对象共识文档
|
||||
# 6A工作流 - CONSENSUS阶段文档
|
||||
|
||||
## 1. 明确的需求描述
|
||||
## 任务名称:Server模块Service缓存调整为Vo对象
|
||||
|
||||
## 1. 需求描述
|
||||
|
||||
### 1.1 基础需求
|
||||
将server模块中所有注解了@CacheConfig的Service类实现的IEntityService接口的泛型参数从实体类类型修改为对应的VO类类型,并同步修改这些Service类中实现的IEntityService接口的所有方法的参数和返回类型。
|
||||
- **修改范围**: server模块中所有注解了@CacheConfig的Service类
|
||||
- **泛型调整**: 调整Service类的接口泛型参数,保持IEntityService泛型为实体类,QueryService泛型为Vo类
|
||||
- **接口实现**: Service类同时实现IEntityService<Model>和QueryService<Vo>接口
|
||||
- **方法适配**: 根据接口要求实现对应的方法,特别处理同名方法的实现
|
||||
- **缓存优化**: 使用VO对象替代实体类进行缓存,彻底避免Hibernate代理对象序列化问题和懒加载异常
|
||||
|
||||
### 1.2 扩展需求
|
||||
使用VO替代实体类进行缓存,避免Hibernate代理对象在Redis序列化过程中可能导致的懒加载异常问题。
|
||||
- **数据转换机制**: 确保从实体类到VO的转换和从VO到实体类的转换逻辑完善且性能良好
|
||||
- **依赖组件处理**: 确保修改后不影响调用Service的其他组件正常运行
|
||||
- **兼容性保障**: 确保WebSocket服务和任务管理等组件能够适配新的接口定义
|
||||
|
||||
### 1.3 需求目标
|
||||
通过将IEntityService接口的泛型从实体类改为VO类,实现接口层与数据访问层的更好解耦,并提高系统的可维护性。同时,通过使用VO对象作为缓存值,彻底解决Redis缓存中的代理对象序列化问题。
|
||||
- **优化缓存机制**: 使用VO对象替代实体类进行缓存,提高系统稳定性和性能
|
||||
- **代码结构优化**: 使Service类的接口实现更加清晰,职责更加明确
|
||||
- **问题解决**: 彻底解决因Hibernate代理对象序列化导致的懒加载异常
|
||||
- **扩展性提升**: 为后续系统扩展和维护奠定良好基础
|
||||
|
||||
## 2. 验收标准
|
||||
|
||||
1. **功能完整性**: 修改后的Service类能够正确实现IEntityService<Vo>接口的所有方法
|
||||
2. **类型一致性**: 所有方法的参数和返回类型与新的泛型参数一致
|
||||
3. **缓存功能**: 缓存配置和注解在修改后仍然有效
|
||||
4. **数据转换**: 正确处理实体类和VO类之间的数据转换
|
||||
5. **系统兼容性**: 修改后不影响系统的其他功能模块
|
||||
6. **编译通过**: 修改后的代码能够成功编译,无编译错误
|
||||
1. **代码修改完整性**: 所有注解了@CacheConfig的Service类都按要求进行了泛型参数调整和方法实现修改
|
||||
- **验证方式**: 代码审查,确保所有符合条件的Service类都被修改
|
||||
|
||||
2. **缓存对象类型**: 所有标注@Cacheable的方法返回VO对象而非实体类对象
|
||||
- **验证方式**: 代码审查,检查@Cacheable注解的方法返回类型
|
||||
|
||||
3. **实体转换机制**: 实体类正确实现Voable接口,提供toVo方法
|
||||
- **验证方式**: 代码审查,确保实体类实现了必要的接口和方法
|
||||
|
||||
4. **功能兼容性**: 修改后系统功能正常运行,没有出现新的错误或异常
|
||||
- **验证方式**: 功能测试,确保核心业务流程正常
|
||||
|
||||
5. **缓存键表达式有效性**: 缓存注解中的键表达式在修改后仍然有效
|
||||
- **验证方式**: 功能测试,确保缓存能够正常工作
|
||||
|
||||
6. **WebSocket服务兼容性**: WebSocket服务能够正常工作,不受Service类修改的影响
|
||||
- **验证方式**: 功能测试,确保WebSocket相关功能正常
|
||||
|
||||
## 3. 技术实现方案
|
||||
|
||||
### 3.1 泛型修改方案
|
||||
|
||||
对于每个注解了@CacheConfig的Service类:
|
||||
|
||||
1. **修改接口声明**:
|
||||
- Service类继承IEntityService接口,泛型类型保持为Model(实体类)
|
||||
- Service类继承QueryService接口,泛型类型修改为Vo(视图对象)
|
||||
|
||||
2. **修改方法签名**: 同步修改所有实现的接口方法的参数和返回类型
|
||||
- findById(Integer id): 根据接口不同返回不同类型(IEntityService返回Model,QueryService返回Vo)
|
||||
- findAll: 根据接口不同参数和返回类型不同
|
||||
- save: 根据接口不同参数和返回类型不同
|
||||
- 对于每个注解了@CacheConfig的Service类,修改其实现的接口为:
|
||||
```java
|
||||
@CacheConfig(cacheNames = "entityCache")
|
||||
public class XXXService implements IEntityService<XXXModel>, QueryService<XXXVo>, VoableService<XXXModel, XXXVo> {
|
||||
// 方法实现
|
||||
}
|
||||
```
|
||||
|
||||
### 3.2 数据转换策略
|
||||
- 实体类实现Voable接口,提供toVo方法:
|
||||
```java
|
||||
public class XXXModel implements Voable<XXXVo> {
|
||||
@Override
|
||||
public XXXVo toVo() {
|
||||
XXXVo vo = new XXXVo();
|
||||
// 进行属性复制
|
||||
return vo;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
1. **实体到VO的转换**:
|
||||
- 为每个Service类添加实体类到VO类的转换方法
|
||||
- 在findById、findAll等返回VO的方法中,使用转换方法将查询到的实体对象转换为VO对象
|
||||
|
||||
2. **VO到实体的转换**:
|
||||
- 在save、delete等接收VO参数的方法中,先将VO对象转换为实体对象,再调用Repository进行操作
|
||||
- 利用现有的VoableService接口提供的updateByVo方法进行属性映射
|
||||
- Service类中的查询方法(如findById、findAll)先查询实体,再转换为Vo对象:
|
||||
```java
|
||||
@Cacheable(key = "#id")
|
||||
@Override
|
||||
public XXXVo findById(Integer id) {
|
||||
Optional<XXXModel> optional = repository.findById(id);
|
||||
return optional.map(XXXModel::toVo).orElse(null);
|
||||
}
|
||||
```
|
||||
|
||||
### 3.3 缓存注解处理
|
||||
|
||||
1. 假设VO类与实体类具有相同的属性结构(如id、code等),因此缓存注解中的键表达式(如@CacheEvict(key = "#p0.id"))可能不需要修改。如果VO类结构不同,需要相应调整缓存键表达式。
|
||||
2. 确保所有标注@Cacheable的方法都返回VO对象,并在存储前完成从实体类到VO的转换,以避免代理对象序列化问题
|
||||
3. 清除Redis中现有的实体类缓存数据,确保新的缓存数据都是VO对象
|
||||
- 保持现有的缓存注解配置不变,确保键表达式仍然有效
|
||||
- 确保所有标注@Cacheable的方法都返回VO对象
|
||||
|
||||
### 3.4 Specification处理
|
||||
|
||||
由于Specification是基于JPA实体类的查询规范,需要特别处理getSpecification方法:
|
||||
|
||||
1. 如果VO类与实体类结构相似,可以保留原有的Specification实现,但需要修改泛型类型
|
||||
2. 如果需要基于VO类属性构建查询,可能需要创建新的转换逻辑
|
||||
- IEntityService接口的getSpecification方法保持返回基于实体类的Specification
|
||||
- QueryService接口的findAll方法中,先使用基于实体类的Specification查询数据,然后转换为Vo对象
|
||||
```java
|
||||
@Override
|
||||
public Page<XXXVo> findAll(JsonNode paramsNode, Pageable pageable) {
|
||||
Specification<XXXModel> spec = getSpecification(paramsNode);
|
||||
Page<XXXModel> page = findAll(spec, pageable);
|
||||
return page.map(XXXModel::toVo);
|
||||
}
|
||||
```
|
||||
|
||||
## 4. 技术约束
|
||||
|
||||
1. **保持接口兼容性**: 不修改IEntityService接口的定义,只修改实现类
|
||||
2. **数据一致性**: 确保实体类和VO类之间的数据转换不会导致数据丢失或不一致
|
||||
3. **事务边界**: 确保修改不会破坏原有的事务处理逻辑
|
||||
4. **性能影响**: 考虑数据转换可能带来的性能影响,必要时进行优化
|
||||
5. **序列化约束**: 确保VO类是可序列化的(实现Serializable接口),避免在VO类中包含不可序列化的引用,确保Redis缓存的序列化和反序列化性能
|
||||
6. **WebSocket服务兼容性**: 确保修改后的IEntityService接口能够与WebSocketServerCallbackManager类兼容,特别是createNewEntity、findEntityTypeInInterfaces等方法
|
||||
7. **类型推断机制**: 确保WebSocketServerCallbackManager中的类型推断机制能够正确处理从实体类到VO类的泛型变化
|
||||
1. **保持接口定义不变**: 不修改IEntityService、QueryService和VoableService接口的定义,只修改实现类
|
||||
|
||||
2. **确保事务一致性**: 修改后不影响现有事务处理逻辑,确保数据一致性
|
||||
|
||||
3. **兼容性保障**: 确保修改后与现有系统和组件的兼容性,特别是WebSocket服务
|
||||
|
||||
4. **性能优化**: 数据转换逻辑应高效,避免性能瓶颈
|
||||
|
||||
5. **错误处理**: 完善异常处理机制,确保系统稳定性
|
||||
|
||||
6. **缓存策略**: 严格遵循缓存策略,避免缓存穿透、缓存雪崩等问题
|
||||
|
||||
7. **代码规范**: 遵循项目现有的代码规范和命名约定
|
||||
|
||||
## 5. 集成方案
|
||||
|
||||
1. **阶段性修改**: 可以按模块或按功能进行阶段性修改,降低风险
|
||||
2. **依赖更新**: 同步更新所有调用修改后Service的组件,确保它们使用新的接口定义
|
||||
3. **测试策略**: 对修改后的Service类进行单元测试和集成测试,验证功能正确性
|
||||
4. **WebSocket服务适配**: 在实施修改时,需要特别关注WebSocketServerCallbackManager类中的方法实现,确保其能够正确处理从实体类到VO类的泛型变化
|
||||
- 测试createNewEntity、findEntityTypeInInterfaces等方法在新泛型参数下的行为
|
||||
- 确保invokerFindByIdMethod、invokerFindAllMethod等方法能够正确处理VO类型的返回值
|
||||
5. **任务管理验证**: 验证WebSocketServerTaskManager类中的任务处理逻辑在接口泛型修改后是否正常工作,特别是涉及到数据转换的部分
|
||||
1. **逐步实施**: 按模块或按业务功能逐步实施修改,降低风险
|
||||
|
||||
2. **测试验证**: 对每个修改的Service类进行单元测试和集成测试
|
||||
|
||||
3. **依赖分析**: 分析修改对其他组件的影响,确保所有依赖都能正确适配
|
||||
|
||||
4. **缓存清理**: 在部署前清理Redis缓存,避免新旧数据混合导致的问题
|
||||
|
||||
5. **监控机制**: 部署后加强监控,及时发现和解决可能出现的问题
|
||||
|
||||
## 6. 任务边界限制
|
||||
|
||||
1. **范围限制**: 仅修改server模块中注解了@CacheConfig的Service类
|
||||
2. **接口限制**: 不修改IEntityService和VoableService接口的定义
|
||||
3. **不涉及功能**: 不添加新功能,仅修改现有功能的实现方式
|
||||
1. **修改范围限制**: 仅修改server模块中注解了@CacheConfig的Service类
|
||||
|
||||
2. **接口定义限制**: 不修改IEntityService、QueryService和VoableService接口的定义
|
||||
|
||||
3. **业务逻辑限制**: 不修改现有业务逻辑,仅调整接口实现和数据转换方式
|
||||
|
||||
## 7. 关键假设确认
|
||||
|
||||
1. **VO类结构**: 假设VO类与对应的实体类具有相似的属性结构,特别是缓存键中使用的属性
|
||||
2. **转换机制**: 假设系统中存在或可以添加实体类与VO类之间的转换机制
|
||||
3. **依赖影响**: 假设修改Service接口不会导致不可预见的依赖问题
|
||||
1. **Vo类结构**: 假设所有Vo类与对应的实体类具有相似的属性结构,特别是ID属性
|
||||
|
||||
2. **接口稳定性**: 假设IEntityService、QueryService和VoableService接口在短时间内不会发生重大变化
|
||||
|
||||
3. **依赖关系**: 假设Service类的主要依赖关系和调用方式不会发生变化
|
||||
|
||||
## 8. 项目特性规范对齐
|
||||
|
||||
- **代码规范**: 遵循项目现有的Java编码规范和命名约定
|
||||
- **文档规范**: 按照6A工作流创建相应的文档
|
||||
- **测试规范**: 为修改后的代码编写测试用例,确保功能正确
|
||||
- **版本控制**: 所有修改通过版本控制系统管理,便于回溯
|
||||
1. **代码风格**: 遵循项目现有的代码风格和命名约定
|
||||
|
||||
以上共识内容已经明确了任务的需求、验收标准、技术实现方案和约束条件,为后续的架构设计和实现阶段提供了清晰的指导。
|
||||
2. **注释规范**: 为新增代码和修改的代码添加适当的JavaDoc注释
|
||||
|
||||
3. **文档同步**: 及时更新相关文档,确保文档与代码的一致性
|
||||
|
||||
4. **测试规范**: 按照项目测试规范编写测试用例,确保代码质量
|
||||
|
||||
所有关键假设已得到确认,任务边界清晰,技术方案与现有架构对齐,验收标准具体可测试。
|
||||
Reference in New Issue
Block a user