springboot+redis缓存方案
一、注解
import java.lang.annotation.elementtype; import java.lang.annotation.retention; import java.lang.annotation.retentionpolicy; import java.lang.annotation.target; import java.util.concurrent.timeunit; /** * @author lch * @date 2023/8/03 09:29 */ @target(elementtype.method) @retention(retentionpolicy.runtime) public @interface rediscache { /** * key,支持 spring el表达式 */ string key(); /** * 统一格式:服务名:场景,如:info */ string prefix(); /** * 过期时间 */ int expiretime() default 36000; /** * 时间单位 */ timeunit timeunit() default timeunit.seconds; }
二、注解切面类
import com.dewav.tms.framework.aspectj.lang.annotation.rediscache; import com.dewav.tms.framework.redis.redisservice; 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.reflect.methodsignature; import org.springframework.context.expression.methodbasedevaluationcontext; import org.springframework.core.defaultparameternamediscoverer; import org.springframework.expression.evaluationcontext; import org.springframework.expression.expression; import org.springframework.expression.spel.standard.spelexpressionparser; import org.springframework.stereotype.component; import org.springframework.util.assert; import javax.annotation.resource; import java.lang.reflect.method; import java.util.concurrent.timeunit; /** * @author lch * @date 2023/8/03 09:29 */ @component @aspect @slf4j public class rediscacheaspect { private final spelexpressionparser spelexpressionparser = new spelexpressionparser(); private final defaultparameternamediscoverer parameternamediscoverer = new defaultparameternamediscoverer(); @resource private redisservice redisservice; @around("@annotation(rediscache)") public object querybyrediscache(proceedingjoinpoint pjp, rediscache rediscache) { int expiretime = rediscache.expiretime(); string key = rediscache.key(); string prefix = rediscache.prefix(); assert.hastext(key, "@rediscache key不能为空!"); assert.hastext(prefix, "@rediscache prefix不能为空!"); string evaluateexpression = evaluateexpression(key, pjp); string rediskey = prefix + evaluateexpression; object obj = null; try { if (null != rediskey){ if (redisservice.haskey(rediskey)){ obj = redisservice.getcacheobject(rediskey); return obj; } } } catch (exception e) { log.error("从redis获取"+rediskey+"失败:"+e.getmessage()); } try{ obj = pjp.proceed(); }catch(throwable e){ log.error("执行异常", e); throw new runtimeexception(e.getmessage()); } if (null != rediskey){ redisservice.setcacheobject(rediskey, obj, expiretime, timeunit.seconds); } return obj; } /** * 解析el表达式 * * @param expression * @param point * @return */ private string evaluateexpression(string expression, proceedingjoinpoint point) { // 获取目标对象 object target = point.gettarget(); // 获取方法参数 object[] args = point.getargs(); methodsignature methodsignature = (methodsignature) point.getsignature(); method method = methodsignature.getmethod(); evaluationcontext context = new methodbasedevaluationcontext(target, method, args, parameternamediscoverer); expression exp = spelexpressionparser.parseexpression(expression); return exp.getvalue(context, string.class); } }
三、使用样例
@override @rediscache(key = "{#customerid + ':' + #dicttype}", prefix = cacheconstants.sys_dict_key) public list<sysdictdata> selectdictdatabytype(long customerid, string dicttype) { return dictdatamapper.selectdictdatabytype(customerid, dicttype); } @override @rediscache(key = "#apikey", prefix = cacheconstants.open_key + "apiinfo:apikey:") public ediapiinfo getbyapikey(string apikey) { return basemapper.selectone(new querywrapper<ediapiinfo>() .eq("api_key", apikey) .eq("status", true) .eq("del_flag", false)); }
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论