最近在做一个类似于教师家访的管理系统,使用的技术架构是SpringCloud,业务架构如下图:
在common共用模块中,有抽取出来的util工具类,用于管理缓存,例如用户缓存工具类UserUtils(存储用户id作为key及用户对象作为value),项目缓存工具类ProjectUtils(存储项目id作为key及项目对象作为value),角色的缓存工具类RoleUtils,分组工具类GroupUtils,表单工具类FormUtils以及问题工具类QuestionUtils等,用来提高查询效率。
但是在查询时,采取的是如果查询不到直接返回空,代码如下:
- /**
- * 获取项目名称
- *
- * @return
- */
- public static String getProjectName(String key) {
- Object cacheObj = SpringUtils.getBean(RedisService.class).getCacheMapValue(getCacheKey(), key);
- if (StringUtils.isNotNull(cacheObj)) {
- String result = StringUtils.cast(cacheObj);
- return result.split(",")[1];
- }
- return null;
- }
此时,如果缓存系统因为淘汰策略淘汰了一些数据,那么生产环境可能会出现事故,所以我们讨论了一下,做了如下包装类:
- public <T> T getName(Long id, String str) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException,
- IllegalAccessException {
-
- QueryNameForCacheEnum enumByCode = QueryNameForCacheEnum.getEnumByCode(str);
- if (Objects.isNull(enumByCode)) {
- return null;
- }
- Class clazz = Class.forName(enumByCode.getClassName());
- Method method = clazz.getMethod(enumByCode.getMethodName(), String.class);
- T res = (T) method.invoke(null, String.valueOf(id));
- if (Objects.isNull(res)) {
- Object remoteObj;
- switch (enumByCode.getRemoteClass()) {
- case "remoteProjectService":
- remoteObj = remoteProjectService;
- break;
- case "remoteRoleService":
- remoteObj = remoteRoleService;
- break;
- case "remoteUserService":
- remoteObj = remoteUserService;
- break;
- default:
- throw new IllegalStateException("Unexpected value");
- }
- Class<?> remoteClazz = remoteObj.getClass();
- Method remoteMethod = remoteClazz.getMethod(enumByCode.getRemoteMethod(), Long.class, String.class);
- remoteMethod.invoke(remoteObj, new Object[]{id, SecurityConstants.INNER});
- res = (T) method.invoke(null, String.valueOf(id));
- }
- return res;
- }
其中枚举类QueryNameForCacheEnum代码如下:
- FROM("form","com.xxx.FormUtils","getFormName","remoteProjectService","setCacheByFormId"),
- GROUP("group","com.xxx.GroupUtils","getGroupName","remoteProjectService","setCacheByGroupId"),
- PROJECT("project","com.xxx.ProjectUtils","getProjectName","remoteProjectService","setCacheByGroupId"),
- ROLE("role","com.xxx..RoleUtils","getRoleName","remoteRoleService","setCacheByRoleId"),
- USER("user","com.xxx.UserUtils","getUserName","remoteUserService","setCacheByUserId"),
做了一个包装,如果调用缓存为空,则调用相关远程类查询一下数据库再进行返回。