本文在—- 手写redis @ cacheable注解支持过期时间设置 的基础之上进行扩展。
@ cacheable(key = “’leader’+#p0 +#p1 +#p2” )一般用法,#p0表示方法的第一个参数,#p1表示第二个参数,以此类推。
目前方法的第一个参数为java的对象,但是原注解只支持java的的基本数据类型。
1.在原注解中加入新的参数,
objectindexarray表示哪几个角标参数(从0开始)为java对象,objectfieldarray表示对应位置该对象的字段值作为key
2.如何获取参数的对象以及该字段的值
使用的java的反射,拼接get方法获取该字段值。
修改java注解@extcacheable,本文中使用@newcacheable
package com.huajie.ann转基因食品安全otation; import java.lang.annotati无法访问windows installer服务on.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.hu四年级下册数学教学计划ajie.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.taccessible(true); // 判断是否存在@extcacheable注解 if (method.isannotationprent(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); } el { object res = joinpoint.proceed(); redisutil.t(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<string> keylist = getkeyparslist(primalkey); for (string keyname : keylist) { int keyindex = integer.parint(keyname.tolowerca().replace("#p", "")); object parvalue = getparvalue(annotation, keyindex, args); primalkey = primalkey.replace(keyname, string.valueof(parvalue)); } return primalkey.replace("+", "").replace("'", ""); 错误633 } 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); } el { 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.firstchartoupperca(objectfieldarray[keyindex])); }el{ method = cls.getmethod("get" + stringutil.firstchartoupperca(cls.getfields()[0].getname())); } method.taccessible(true); log.info(method.getname()); return method.invoke(args[keyindex]); } private boolean existsobject(int keyindex, int[] objectindexarray) { if (objectindexarray == null || objectindexarray.length <= 0) { return fal; } for (int i = 0; i < objectindexarray.length; i++) { if (keyindex == objectindexarray[i]) { return true; } } return fal; } // 获取key中#p0中的参数名称 private static list<string> getkeyparslist(string key) { list<string> listpar = new arraylist<string>(); 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); } el { parname = key.substring(indexpre); } listpar.add(parname.trim()); key = key.substring(indexnext + 1); if (key.indexof("#") >= 0) { listpar.addall(getkeyparslist(key)); } } return listpar; } }
业务模块使用方法controller
@requestmapping("queryquotatreedata")@responbodypublic list<treenode> gettreedata() {quotamanage quotamanage = new quotamanage();quotamanage.tquotaname("测试22222");list<treenode> list = this.quotamanagervice.queryquotatreedata(quotamanage);return list;}
实现层objectindexarray中的{0}表示第0个参数,objectfieldarray中的“quotaname”表示对应对象中的字段名称
@override@newcacheable(key="test+#p0",objectindexarray = {0},objectfieldarray = {"quotaname"})public list<t抑郁测试题reenode> queryquotatreedata(quotamanage quotamanage) {list<treenode> returnnodeslist = new arraylist<treenode>();list<treenode> nodelist = this.mapper.queryquotatreedata();returnnodeslist = treeutils.getparentlist(nodelist);log.info(nodelist.size()+"");return returnnodeslist;}
控制台截图拼接的get方法名称和获取的字段值
redis的截图
以上为个人经验,希望能给大家一个参考,也希望大家多多支持www.887551.com。
本文发布于:2023-04-04 09:46:42,感谢您对本站的认可!
本文链接:https://www.wtabcd.cn/fanwen/zuowen/c77263f0babfc695e6293a858abb134b.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文word下载地址:手写redis@Cacheable注解 参数java对象作为key值详解.doc
本文 PDF 下载地址:手写redis@Cacheable注解 参数java对象作为key值详解.pdf
留言与评论(共有 0 条评论) |