「这是我参与2022首次更文挑战的第16天,活动详情查看:2022首次更文挑战」
1、问题引入
当我们遇到复杂结构的redis数据更新时,如何将原始数据存到数据库后组装同步到redis?然后,在项目中还有一个需求就是有些数据入库后,需要通过MQ发送到其他服务。所以就将其整合成了一个公共的功能,只需要通过配置、写好自己的处理器即可,这样就去除了重复、繁琐的代码。下面就先为大家介绍下具体实现。
2、复杂结构Redis数据更新的实现
//根据配置信息更新缓存
@Component
public class CacheUpdateComponent {
@Resource(name = "rabbitTemplate")
private RabbitTemplate rabbitTemplate;
/**
* 判断sqlid是否在缓存配置中, 如果存在,则进行缓存更新操作
* @param execonfig 执行对sqlid集合
* @param params 参数
* @throws KPromptException
*/
public void judgeSqlIdExistByConfig(SqlExecute execonfig, Map<String, Object> params) throws PromptException {
try {
judgeSqlIdExistByConfig(execonfig.getSqlids(), params);
} catch (Exception e) {
logger.error("更新缓存失败:" + e.getMessage(), e);
throw new PromptException("更新缓存失败:" + e.getMessage());
}
}
public void judgeSqlIdExistByConfig(List<String> execonfigSqlIds, Map<String, Object> params) throws KPromptException {
boolean flag;
for (String exeSqlId:execonfigSqlIds) {
try {
flag = CacheUtil.existsKey(RedisKeyNameEntity.CACHE_CONFIG_NAME + exeSqlId, true);
// 非缓存配置页面进行的操作
if (flag) {
CacheConfigInfo configInfo = JSONObject.parseObject(SysBeans.getCacheAble().getCache(RedisKeyNameEntity.CACHE_CONFIG_NAME + exeSqlId, true), CacheConfigInfo.class);
// 对redis进行更新
if (CacheConfigStatusEntity.REDIS_STATUS_YES.equals(configInfo.getRedisStatus())){
String redisValueType = configInfo.getRedisValueType();
String redisPrefixHooks = configInfo.getRedisPrefixHooks();
if(null != redisPrefixHooks && !redisPrefixHooks.isEmpty()){
params = (Map<String, Object>) KInvoke.invokeDistributedHander(redisPrefixHooks, params);
}
if(null != configInfo.getRedisNonCacheKey() && !configInfo.getRedisNonCacheKey().isEmpty()) {
if(RedisValueTypeEntity.HASH.equals(redisValueType)) {
SysBeans.getCacheAble().setMap(CacheUtil.cacheKeyHandler(configInfo.getRedisParamKey(), configInfo.getRedisPrefix(), params), true, CacheUtil.cacheMapValHandler(CacheUtil.cacheValHandler(configInfo.getRedisNonCacheKey(), params)));
}else {
SysBeans.getCacheAble().setCache(CacheUtil.cacheKeyHandler(configInfo.getRedisParamKey(), configInfo.getRedisPrefix(), params), JSON.toJSONString(CacheUtil.cacheValHandler(configInfo.getRedisNonCacheKey(), params)), true);
}
}else {
if(RedisValueTypeEntity.HASH.equals(redisValueType)) {
SysBeans.getCacheAble().setMap(CacheUtil.cacheKeyHandler(configInfo.getRedisParamKey(), configInfo.getRedisPrefix(), params), true, CacheUtil.cacheMapValHandler(params));
}else {
SysBeans.getCacheAble().setCache(CacheUtil.cacheKeyHandler(configInfo.getRedisParamKey(), configInfo.getRedisPrefix(), params), JSON.toJSONString(params), true);
}
}
String redisBehindHooks = configInfo.getRedisBehindHooks();
if(null != redisBehindHooks && !redisBehindHooks.isEmpty()) {
KInvoke.invokeTechnologiesHander(redisBehindHooks, params);
}
}
// 对mq进行更新
if (CacheConfigStatusEntity.MQ_STATUS_YES.equals(configInfo.getMqStatus())){
//获取前置hook函数
String mqPrefixHooks = configInfo.getMqPrefixHooks();
if(null != mqPrefixHooks && !mqPrefixHooks.isEmpty()){
params = (Map<String, Object>) KInvoke.invokeDistributedHander(mqPrefixHooks, params);
}
if (null != configInfo.getMqRoutingKey() && !configInfo.getMqRoutingKey().isEmpty()) {
rabbitTemplate.convertAndSend(configInfo.getMqName(), configInfo.getMqRoutingKey(), params);
}else {
rabbitTemplate.convertAndSend(configInfo.getMqName(), params);
}
String mqBehindHooks = configInfo.getMqBehindHooks();
if(null != mqBehindHooks && !mqBehindHooks.isEmpty()) {
KInvoke.invokeTechnologiesHander(mqBehindHooks, params);
}
}
}
} catch (Exception e) {
logger.error("更新缓存失败:" + e.getMessage(), e);
throw new PromptException("更新缓存失败:" + e.getMessage());
}
}
}
}
//对于redis缓存之前的钩子函数的执行,是通过反射完成的,这里也为大家分享下反射工具类
public class InvokeUtil {
/**
* 反射处理器(无入参、无返回)
* @param invokeConfig 反射配置 格式:报名.类名.方法名
* @return
* @throws Exception
*/
public static void invokeTechnologiesHander(String invokeConfig) throws Exception {
String[] hC = invokeConfig.split("\\.");
if(1 > hC.length) {
throw new KPromptException("反射配置错误,配置信息为:[" + invokeConfig + "]");
}
String methodName = hC[hC.length-1];
String className = invokeConfig.substring(0, invokeConfig.indexOf(methodName)-1);
Object obj = getInvokeObj(className);
Method method = getInvokeMethod(methodName, obj.getClass());
method.invoke(obj);
}
/**
* 反射处理器(无入参、无返回)
* @param invokeConfig 反射配置 格式:报名.类名 + 分隔符 + 方法名
* @param separator 分隔符
* @return
* @throws Exception
*/
public static void invokeTechnologiesHander(String invokeConfig, String separator) throws Exception {
String[] hC = invokeConfig.split("\\" + separator);
if(1 > hC.length) {
throw new KPromptException("反射配置错误,配置信息为:[" + invokeConfig + "]");
}
String methodName = hC[hC.length-1];
String className = invokeConfig.substring(0, invokeConfig.indexOf(methodName)-1);
Object obj = getInvokeObj(className);
Method method = getInvokeMethod(methodName, obj.getClass());
method.invoke(obj);
}
/**
* 反射处理器(有入参、无返回)
* @param invokeConfig 反射配置 格式:报名.类名.方法名
* @param args 参数
* @return
* @throws Exception
*/
public static void invokeTechnologiesHander(String invokeConfig, Object... args) throws Exception {
String[] hC = invokeConfig.split("\\.");
if(1 > hC.length) {
throw new KPromptException("反射配置错误,配置信息为:[" + invokeConfig + "]");
}
String methodName = hC[hC.length-1];
String className = invokeConfig.substring(0, invokeConfig.indexOf(methodName)-1);
Object obj = getInvokeObj(className);
Method method = getInvokeMethod(methodName, obj.getClass(), objToClassArr(args));
method.invoke(obj, args);
}
/**
* 反射处理器(有入参、无返回)
* @param invokeConfig 反射配置 格式:报名.类名 + 分隔符 + 方法名
* @param separator 分隔符
* @param args 参数
* @return
* @throws Exception
*/
public static void invokeTechnologiesHander(String invokeConfig, String separator, Object... args) throws Exception {
String[] hC = invokeConfig.split("\\" + separator);
if(1 > hC.length) {
throw new KPromptException("反射配置错误,配置信息为:[" + invokeConfig + "]");
}
String methodName = hC[hC.length-1];
String className = invokeConfig.substring(0, invokeConfig.indexOf(methodName)-1);
Object obj = getInvokeObj(className);
Method method = getInvokeMethod(methodName, obj.getClass(), objToClassArr(args));
method.invoke(obj, args);
}
/**
* 反射处理器(无入参、有返回)
* @param invokeConfig 反射配置 格式:报名.类名.方法名
* @return
* @throws Exception
*/
public static Object invokeDistributedHander(String invokeConfig) throws Exception {
String[] hC = invokeConfig.split("\\.");
if(1 > hC.length) {
throw new KPromptException("反射配置错误,配置信息为:[" + invokeConfig + "]");
}
String methodName = hC[hC.length-1];
String className = invokeConfig.substring(0, invokeConfig.indexOf(methodName)-1);
Object obj = getInvokeObj(className);
Method method = getInvokeMethod(methodName, obj.getClass());
return method.invoke(obj);
}
/**
* 反射处理器(无入参、有返回)
* @param invokeConfig 反射配置 格式:报名.类名 + 分隔符 + 方法名
* @param separator 分隔符
* @return
* @throws Exception
*/
public static Object invokeDistributedHander(String invokeConfig, String separator) throws Exception {
String[] hC = invokeConfig.split("\\" + separator);
if(1 > hC.length) {
throw new KPromptException("反射配置错误,配置信息为:[" + invokeConfig + "]");
}
String methodName = hC[hC.length-1];
String className = invokeConfig.substring(0, invokeConfig.indexOf(methodName)-1);
Object obj = getInvokeObj(className);
Method method = getInvokeMethod(methodName, obj.getClass());
return method.invoke(obj);
}
/**
* 反射处理器(有入参、有返回)
* @param invokeConfig 反射配置 格式:包名.类名.方法名
* @param args 参数
* @return
* @throws Exception
*/
public static Object invokeDistributedHander(String invokeConfig, Object... args) throws Exception {
String[] hC = invokeConfig.split("\\.");
if(1 > hC.length) {
throw new KPromptException("反射配置错误,配置信息为:[" + invokeConfig + "]");
}
String methodName = hC[hC.length-1];
String className = invokeConfig.substring(0, invokeConfig.indexOf(methodName)-1);
Object obj = getInvokeObj(className);
Method method = getInvokeMethod(methodName, obj.getClass(), objToClassArr(args));
return method.invoke(obj, args);
}
/**
* 反射处理器(有入参、有返回)
* @param invokeConfig 反射配置 格式:包名.类名 + 分隔符 + 方法名
* @param separator 分隔符
* @param args 参数
* @return
* @throws Exception
*/
public static Object invokeDistributedHander(String invokeConfig, String separator, Object... args) throws Exception {
String[] hC = invokeConfig.split("\\" + separator);
if(1 > hC.length) {
throw new PromptException("反射配置错误,配置信息为:[" + invokeConfig + "]");
}
String methodName = hC[hC.length-1];
String className = invokeConfig.substring(0, invokeConfig.indexOf(methodName)-1);
Object obj = getInvokeObj(className);
Method method = getInvokeMethod(methodName, obj.getClass(), objToClassArr(args));
return method.invoke(obj, args);
}
/**
* 获取反射(无入参)方法
* @param methodName 方法名称
* @param cls 反射类
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public static Method getInvokeMethod(String methodName, Class cls) throws Exception {
return cls.getDeclaredMethod(methodName);
}
/**
* 获取反射(有入参)方法
* @param methodName 方法名称
* @param cls 反射类
* @param paramClass 参数类
* @return
* @throws Exception
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public static Method getInvokeMethod(String methodName, Class cls, Class<?>... paramClass) throws Exception {
return cls.getDeclaredMethod(methodName, paramClass);
}
/**
* 获取返回类实例(对象)
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public static Object getInvokeObj(String className) throws Exception {
Class cls = Class.forName(className);
return cls.getConstructor().newInstance();
}
/**
*
* @param args
* @return
*/
@SuppressWarnings("rawtypes")
private static Class[] objToClassArr(Object... args) {
Class[] classs = new Class[args.length];
for(int i = 0; i < args.length; i++) {
classs[i] = args[i].getClass();
}
return classs;
}
}
好了、本期就先介绍到这里,有什么需要交流的,大家可以随时私信我。😊