java对象作为key值的实例分析
发表于:2026-11-02 作者:千家信息网编辑
千家信息网最后更新 2026年11月02日,这篇文章给大家介绍java对象作为key值的实例分析,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。1.实现方式说明下面在---- 手写redis @ Cacheable注解支持过
千家信息网最后更新 2026年11月02日java对象作为key值的实例分析
这篇文章给大家介绍java对象作为key值的实例分析,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。
1.实现方式说明
下面在---- 手写redis @ Cacheable注解支持过期时间设置 的基础之上进行扩展。
1.1问题说明
@ Cacheable(key = "'leader'+#p0 +#p1 +#p2" )一般用法,#p0表示方法的第一个参数,#p1表示第二个参数,以此类推。
目前方法的第一个参数为Java的对象,但是原注解只支持Java的的基本数据类型。
1.2实现步骤
1.在原注解中加入新的参数,
objectIndexArray表示哪几个角标参数(从0开始)为java对象,objectFieldArray表示对应位置该对象的字段值作为key
2.如何获取参数的对象以及该字段的值
使用的java的反射,拼接get方法获取该字段值。
2.源代码
修改java注解@ExtCacheable,本文中使用@NewCacheable
package com.huajie.annotation; import java.lang.annotation.ElementType;import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;import java.lang.annotation.Target; @Target({ ElementType.METHOD })@Retention(RetentionPolicy.RUNTIME)public @interface NewCacheable { String key() default ""; int[] objectIndexArray(); String[] objectFieldArray(); int expireTime() default 1800;//30分钟 }SpringAop切面NewCacheableAspect
获取AOP整体流程没有任何变化
主要是关键值获取的方式,发生了变化

使用Java的反射技术

完整代码如下:
package com.huajie.aspect; import com.huajie.annotation.NewCacheable;import com.huajie.utils.RedisUtil;import com.huajie.utils.StringUtil;import lombok.extern.slf4j.Slf4j;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Pointcut;import org.aspectj.lang.reflect.MethodSignature;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Component;import java.lang.reflect.Method;import java.util.ArrayList;import java.util.List; /** * redis缓存处理 不适用与内部方法调用(this.)或者private */@Component@Aspect@Slf4jpublic class NewCacheableAspect { @Autowired private RedisUtil redisUtil; @Pointcut("@annotation(com.huajie.annotation.NewCacheable)") public void annotationPointcut() { } @Around("annotationPointcut()") public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable { // 获得当前访问的class Class> className = joinPoint.getTarget().getClass(); // 获得访问的方法名 String methodName = joinPoint.getSignature().getName(); // 得到方法的参数的类型 Class>[] argClass = ((MethodSignature) joinPoint.getSignature()).getParameterTypes(); Object[] args = joinPoint.getArgs(); String key = ""; int expireTime = 3600; try { // 得到访问的方法对象 Method method = className.getMethod(methodName, argClass); method.setAccessible(true); // 判断是否存在@ExtCacheable注解 if (method.isAnnotationPresent(NewCacheable.class)) { NewCacheable annotation = method.getAnnotation(NewCacheable.class); key = getRedisKey(args, annotation); expireTime = getExpireTime(annotation); } } catch (Exception e) { throw new RuntimeException("redis缓存注解参数异常", e); } log.info(key); boolean hasKey = redisUtil.hasKey(key); if (hasKey) { return redisUtil.get(key); } else { Object res = joinPoint.proceed(); redisUtil.set(key, res); redisUtil.expire(key, expireTime); return res; } } private int getExpireTime(NewCacheable annotation) { return annotation.expireTime(); } private String getRedisKey(Object[] args, NewCacheable annotation) throws Exception{ String primalKey = annotation.key(); // 获取#p0...集合 List keyList = getKeyParsList(primalKey); for (String keyName : keyList) { int keyIndex = Integer.parseInt(keyName.toLowerCase().replace("#p", "")); Object parValue = getParValue(annotation, keyIndex, args); primalKey = primalKey.replace(keyName, String.valueOf(parValue)); } return primalKey.replace("+", "").replace("'", ""); } private Object getParValue(NewCacheable annotation, int keyIndex, Object[] args) throws Exception{ int[] objectIndexArray = annotation.objectIndexArray(); String[] objectFieldArray = annotation.objectFieldArray(); if (existsObject(keyIndex, objectIndexArray)) { return getParValueByObject(args, keyIndex, objectFieldArray); } else { return args[keyIndex]; } } private Object getParValueByObject(Object[] args, int keyIndex, String[] objectFieldArray) throws Exception { Class cls = args[keyIndex].getClass(); Method method; if(objectFieldArray!=null&&objectFieldArray.length>=keyIndex){ method = cls.getMethod("get" + StringUtil.firstCharToUpperCase(objectFieldArray[keyIndex])); }else{ method = cls.getMethod("get" + StringUtil.firstCharToUpperCase(cls.getFields()[0].getName())); } method.setAccessible(true); log.info(method.getName()); return method.invoke(args[keyIndex]); } private boolean existsObject(int keyIndex, int[] objectIndexArray) { if (objectIndexArray == null || objectIndexArray.length <= 0) { return false; } for (int i = 0; i < objectIndexArray.length; i++) { if (keyIndex == objectIndexArray[i]) { return true; } } return false; } // 获取key中#p0中的参数名称 private static List getKeyParsList(String key) { List ListPar = new ArrayList(); if (key.indexOf("#") >= 0) { int plusIndex = key.substring(key.indexOf("#")).indexOf("+"); int indexNext = 0; String parName = ""; int indexPre = key.indexOf("#"); if (plusIndex > 0) { indexNext = key.indexOf("#") + key.substring(key.indexOf("#")).indexOf("+"); parName = key.substring(indexPre, indexNext); } else { parName = key.substring(indexPre); } ListPar.add(parName.trim()); key = key.substring(indexNext + 1); if (key.indexOf("#") >= 0) { ListPar.addAll(getKeyParsList(key)); } } return ListPar; } } 3.测试
业务模块使用方法controller
@RequestMapping("queryQuotaTreeData") @ResponseBody public List getTreeData() { QuotaManage quotaManage = new QuotaManage(); quotaManage.setQuotaName("测试22222"); List list = this.quotaManageService.queryQuotaTreeData(quotaManage); return list; } 实现层objectIndexArray中的{0}表示第0个参数,objectFieldArray中的"quotaName"表示对应对象中的字段名称
@Override @NewCacheable(key="test+#p0",objectIndexArray = {0},objectFieldArray = {"quotaName"}) public List queryQuotaTreeData(QuotaManage quotaManage) { List returnNodesList = new ArrayList(); List nodeList = this.mapper.queryQuotaTreeData(); returnNodesList = treeUtils.getParentList(nodeList); log.info(nodeList.size()+""); return returnNodesList; } 控制台截图拼接的get方法名称和获取的字段值
Redis的截图
关于java对象作为key值的实例分析就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。
参数
方法
对象
注解
字段
名称
实例
实例分析
分析
内容
截图
方式
更多
类型
缓存
反射
变化
帮助
支持
测试
数据库的安全要保护哪些东西
数据库安全各自的含义是什么
生产安全数据库录入
数据库的安全性及管理
数据库安全策略包含哪些
海淀数据库安全审计系统
建立农村房屋安全信息数据库
易用的数据库客户端支持安全管理
连接数据库失败ssl安全错误
数据库的锁怎样保障安全
科技信息互联网
奇酷互联网科技
成都互联网科技公司
南京欣网互联网科技
互联网金融科技平台
顺玮阁互联网科技
天下捷融互联网科技
互联网科技公司招聘
富国互联网科技创新基金
西藏七维空间互联网科技有限公司
深圳前海聚择互联网科技有限公司
恒生互联网科技指数跳水
乌鲁木齐新华智原互联网科技学校
高科技互联网发展前景如何
富国互联网金融科技混合基金
江苏互联网科技小贷
互联网界的黑科技
互联网金融金融科技
平安好医生打造互联网科技医疗
互联网科技创新方面的资料
喔噻互联网科技有限公司
互联网科技工作委员会
科技互联网企业
美国互联网黑科技
米客互联网科技
深圳前海聚择互联网科技有限公司
互联网科技大赛获奖感言
2021互联网科技公司排名
扫呗互联网科技有限公司
西安左小互联网科技有限公司