Springboot Cache @CacheEvict 无法模糊删除的解决方案
程序员文章站
2022-06-24 10:42:28
目录springbootcache @cacheevict 无法模糊删除以下代码适用于redis@cacheevict根据缓存名称模糊删除看源码可知springbootcache @cacheevic...
springbootcache @cacheevict 无法模糊删除
用@cacheevict删除缓存只能删除指定key的缓存,有些情况需要根据前缀删除所有key的时候,用@cacheevict就做不到了,所以我们自定义一个@cacheremove来处理根据前缀模糊删除所有cache(支持spring el表达式)
以下代码适用于redis
添加依赖
<dependency> <groupid>org.springframework.boot</groupid> <artifactid>spring-boot-starter-aop</artifactid> </dependency>
启动类加上 @enableaspectjautoproxy
@cacheremove 代码
package com.marssvn.utils.annotation.cache; import java.lang.annotation.retention; import java.lang.annotation.retentionpolicy; import java.lang.annotation.target; import static java.lang.annotation.elementtype.method; @target({method}) @retention(retentionpolicy.runtime) public @interface cacheremove { string[] value() default {}; }
cacheremoveaspect aop实现类代码
package com.marssvn.utils.annotation.cache.aspect; import com.marssvn.utils.annotation.cache.cacheremove; import org.aspectj.lang.joinpoint; import org.aspectj.lang.annotation.afterreturning; import org.aspectj.lang.annotation.aspect; import org.aspectj.lang.reflect.methodsignature; import org.slf4j.logger; import org.slf4j.loggerfactory; import org.springframework.core.localvariabletableparameternamediscoverer; import org.springframework.data.redis.core.stringredistemplate; import org.springframework.expression.expressionparser; import org.springframework.expression.spel.standard.spelexpressionparser; import org.springframework.expression.spel.support.standardevaluationcontext; import org.springframework.stereotype.component; import javax.annotation.resource; import java.lang.reflect.method; import java.util.set; @aspect @component public class cacheremoveaspect { @resource private stringredistemplate stringredistemplate; private logger logger = loggerfactory.getlogger(this.getclass()); @afterreturning("@annotation(com.marssvn.utils.annotation.cache.cacheremove)") public void remove(joinpoint point) { method method = ((methodsignature) point.getsignature()).getmethod(); cacheremove cacheremove = method.getannotation(cacheremove.class); string[] keys = cacheremove.value(); for (string key : keys) { if (key.contains("#")) key = parsekey(key, method, point.getargs()); set<string> deletekeys = stringredistemplate.keys(key); stringredistemplate.delete(deletekeys); logger.info("cache key: " + key + " deleted"); } } /** * parsekey from spel */ private string parsekey(string key, method method, object [] args){ localvariabletableparameternamediscoverer u = new localvariabletableparameternamediscoverer(); string[] paranamearr = u.getparameternames(method); expressionparser parser = new spelexpressionparser(); standardevaluationcontext context = new standardevaluationcontext(); for (int i = 0; i < paranamearr.length; i++) { context.setvariable(paranamearr[i], args[i]); } return parser.parseexpression(key).getvalue(context, string.class); } }
service中的调用代码
/** * delete repository * * @param id repositoryid */ @override @transactional @cacheremove({"repository.list::*", "'repository::id=' + #id", "'repository.tree::id=' + #id + '*'"}) public void deleterepositorybyid(int id) { // business code }
@cacheevict根据缓存名称模糊删除
@cacheevict(cachenames = "likename" ,allentries=true)
-
allentries=true
开启全匹配 -
cachenames
填写 模糊删除的name
看源码可知
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。