# WebSocket服务组件修改方案 ## 1. 概述 基于对WebSocket服务组件的分析,本方案提出对WebSocketServerCallbackManager类进行优化,重点改进泛型类型处理逻辑、增强类型安全检查、实现类型缓存机制,以提高系统的性能、稳定性和可维护性。 ## 2. 修改目标 1. 实现类型缓存机制,避免重复解析泛型参数 2. 优化类型解析逻辑,提高代码可读性和健壮性 3. 增加类型安全检查,防止运行时类型错误 4. 完善错误处理机制,提供更详细的异常信息 5. 增强对Spring代理类的处理能力 ## 3. 详细修改方案 ### 3.1 优化WebSocketServerCallbackManager类 #### 3.1.1 实现类型缓存机制 在WebSocketServerCallbackManager类中添加一个静态缓存Map,用于存储已解析的实体类型: ```java // 添加类型缓存,避免重复解析泛型参数 private static final Map, Class> ENTITY_TYPE_CACHE = new ConcurrentHashMap<>(); /** * 从缓存获取实体类型 */ @SuppressWarnings("unchecked") private Class getEntityTypeFromCache(Class serviceClass) { return (Class) ENTITY_TYPE_CACHE.get(serviceClass); } /** * 缓存实体类型 */ private void cacheEntityType(Class serviceClass, Class entityClass) { ENTITY_TYPE_CACHE.put(serviceClass, entityClass); } ``` #### 3.1.2 优化createNewEntity方法 修改createNewEntity方法,使用缓存机制并优化类型解析逻辑: ```java private T createNewEntity(IEntityService entityService) { try { // 获取服务类 Class serviceClass = entityService.getClass(); // 1. 尝试从缓存获取实体类型 Class entityClass = getEntityTypeFromCache(serviceClass); if (entityClass != null) { return createInstance(entityClass); } // 2. 直接检查接口 entityClass = findEntityTypeInInterfaces(serviceClass); if (entityClass != null) { cacheEntityType(serviceClass, entityClass); return createInstance(entityClass); } // 3. 处理Spring代理类 - 获取原始类 Class targetClass = getTargetClass(serviceClass); if (targetClass != serviceClass) { entityClass = findEntityTypeInInterfaces(targetClass); if (entityClass != null) { cacheEntityType(serviceClass, entityClass); return createInstance(entityClass); } } // 4. 尝试查找父类 entityClass = findEntityTypeInSuperclass(serviceClass); if (entityClass != null) { cacheEntityType(serviceClass, entityClass); return createInstance(entityClass); } // 5. 如果上述方法都失败,尝试从参数类型推断 entityClass = findEntityTypeFromMethodParameters(serviceClass); if (entityClass != null) { cacheEntityType(serviceClass, entityClass); return createInstance(entityClass); } // 如果所有方法都失败,抛出更具描述性的异常 throw new UnsupportedOperationException( String.format("无法确定实体类型,请检查服务实现: %s, 实现的接口: %s", serviceClass.getName(), Arrays.toString(serviceClass.getInterfaces()))); } catch (Exception e) { throw new RuntimeException("无法创建Entity实例: " + e.getMessage(), e); } } /** * 创建实例的辅助方法 */ private T createInstance(Class entityClass) { try { return entityClass.getDeclaredConstructor().newInstance(); } catch (Exception e) { throw new RuntimeException( String.format("无法创建%s的实例,请确保该类有公共无参构造函数", entityClass.getName()), e); } } ``` #### 3.1.3 增强类型安全检查 在各个方法中增加类型安全检查,防止类型转换错误: ```java private Object invokerSaveMethod(Object service, JsonNode argumentsNode) throws JsonMappingException { JsonNode paramsNode = argumentsNode.get(0); if (service instanceof IEntityService entityService) { Object entity = null; if (paramsNode.has("id") && !paramsNode.get("id").isNull()) { int id = paramsNode.get("id").asInt(); entity = entityService.getById(id); if (entity == null) { throw new NoSuchElementException("未找到实体: #" + id); } } else { entity = createNewEntity(entityService); } if (service instanceof VoableService) { String typeClz = argumentsNode.get(1).asText(); Class type = null; try { type = Class.forName(typeClz); // 增加类型安全检查 if (!VoableService.class.isAssignableFrom(service.getClass())) { throw new IllegalArgumentException( String.format("服务%s未实现VoableService接口", service.getClass().getName())); } } catch (ClassNotFoundException e) { throw new RuntimeException("无法加载类型: " + typeClz, e); } Object object = objectMapper.convertValue(paramsNode, type); ((VoableService) service).updateByVo(entity, object); } else { objectMapper.updateValue(entity, paramsNode); } return ((IEntityService) entityService).save(entity); } throw new IllegalArgumentException( String.format("服务%s未实现IEntityService接口", service.getClass().getName())); } ``` #### 3.1.4 优化findAll方法的类型处理 ```java private Object invokerFindAllMethod(Object service, JsonNode argumentsNode) throws JsonProcessingException { // 增加类型安全检查 if (!(service instanceof QueryService)) { throw new IllegalArgumentException( String.format("服务%s未实现QueryService接口", service.getClass().getName())); } JsonNode paramsNode = argumentsNode.get(0); JsonNode pageableNode = argumentsNode.get(1); // 增加参数校验 if (pageableNode == null) { throw new IllegalArgumentException("分页参数不能为空"); } PageArgument pageArgument = objectMapper.treeToValue(pageableNode, PageArgument.class); QueryService queryService = (QueryService) service; try { Page page = queryService.findAll(paramsNode, pageArgument.toPageable()); return PageContent.of(page.map(entity -> { if (entity instanceof Voable) { return ((Voable) entity).toVo(); } return entity; })); } catch (Exception e) { throw new RuntimeException("查询数据失败: " + e.getMessage(), e); } } ``` #### 3.1.5 增强getTargetClass方法 增强对Spring代理类的处理能力: ```java /** * 获取被代理的原始类 */ private Class getTargetClass(Class proxyClass) { // 处理CGLIB代理类 if (proxyClass.getName().contains("$$SpringCGLIB$$")) { Class superClass = proxyClass.getSuperclass(); // 确保返回的不是Object类 return (superClass != null && superClass != Object.class) ? superClass : proxyClass; } // 处理JDK动态代理类 if (Proxy.isProxyClass(proxyClass)) { InvocationHandler handler = Proxy.getInvocationHandler(proxyClass); // 这里可以根据实际情况进一步处理JDK代理类 } return proxyClass; } ``` ### 3.2 添加日志和监控 在关键方法中添加详细日志,方便问题排查和性能监控: ```java private Object handleAsMessageCallback(SessionInfo session, String messageId, JsonNode jsonNode) throws Exception { long startTime = System.currentTimeMillis(); logger.debug("开始处理消息回调: {}, 服务: {}, 方法: {}", messageId, jsonNode.get(WebSocketConstant.SERVICE_FIELD_NAME), jsonNode.get(WebSocketConstant.METHOD_FIELD_NAME)); try { // 原有逻辑... Object result = null; // 处理逻辑... logger.debug("处理消息回调完成: {}, 耗时: {}ms", messageId, (System.currentTimeMillis() - startTime)); return result; } catch (Exception e) { logger.error("处理消息回调失败: {}, 耗时: {}ms", messageId, (System.currentTimeMillis() - startTime), e); throw e; } } ``` ## 4. 测试用例设计 为了验证修改后的WebSocket服务组件的正确性和性能,建议设计以下测试用例: ### 4.1 功能测试 1. **基本CRUD操作测试**:测试通过WebSocket进行实体的创建、查询、更新和删除操作 2. **分页查询测试**:测试不同分页参数下的查询功能 3. **类型安全测试**:测试各种边缘情况下的类型处理是否正确 ### 4.2 性能测试 1. **并发请求测试**:模拟多用户并发访问WebSocket服务 2. **缓存效果测试**:验证类型缓存机制的性能提升效果 ### 4.3 异常处理测试 1. **参数错误测试**:测试各种参数错误情况下的异常处理 2. **类型转换错误测试**:测试类型转换失败情况下的异常处理 ## 5. 实施计划 1. **准备阶段**:创建分析报告和修改方案文档 2. **编码阶段**:按照修改方案实现代码优化 3. **测试阶段**:编写并执行测试用例,验证修改效果 4. **验证阶段**:生成验证报告,确认修改满足需求 ## 6. 风险评估 1. **兼容性风险**:修改可能影响现有功能的兼容性 - 应对措施:全面测试,确保与现有系统兼容 2. **性能风险**:缓存机制可能引入内存占用增加的风险 - 应对措施:监控内存使用情况,必要时调整缓存策略 3. **实现风险**:优化逻辑可能引入新的bug - 应对措施:编写详细的测试用例,进行充分测试 ## 7. 总结 本修改方案针对WebSocket服务组件中的泛型类型处理问题提出了全面的优化措施,包括实现类型缓存机制、优化类型解析逻辑、增强类型安全检查、完善错误处理机制等。这些优化将有助于提高系统的性能、稳定性和可维护性,为后续的功能扩展奠定良好基础。