首页 > 作文

手写redis@Cacheable注解 参数java对象作为key值详解

更新时间:2023-04-04 09:46:43 阅读: 评论:0

目录
1.实现方式说明1.1问题说明1.2实现步骤2.源代码3.测试

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.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;    } }

3.测试

业务模块使用方法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 条评论)
   
验证码:
Copyright ©2019-2022 Comsenz Inc.Powered by © 专利检索| 网站地图