@CacheEvict只能单一清除的扩展 -模糊-正则清除多条缓存 解决
2018-09-14 17:56
597 查看
1.@CacheEvic(value="xx",key="xxx")只能单一删除,但是
[code] @Cacheable(value = "autocms", key = "#root.targetClass+'.'+#root.method.name+'.'+#p0+'.'+#p1") public <T> PageInfo<T> getActivityByShowStatus(Map<String, Integer> paramMap, Class<T> cl) {
会根据不同的参数生成多条缓存数据,之久导致的当出现数据更新的时候更新缓存的困难
解决:
首先找到这一类的缓存的共同点,同一类缓存有着相同的前缀,而java redis客户端支持正则查询和批量的删除
1.问题一:在需要刷新的缓存的时候如何拿到这个前缀,这个问题的取决于你的前缀或者后缀是如何生成的
2.问题二:就是你如何的根据前缀或者后缀去清除redis缓存
实现方式
1.你可以写个工具类,
2写一个服务类注入到Spring中使用的时候直接拿出来
3.你可以使用Sring的Aop代理增强的方式进行处理
我是先使用的第二种,后来改成了第三种
下面直接上代码,代码里面都有注释
[code]import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * 功能描述:需要清除的当前类型--当前类 * * @author fuyuchao * DATE 2018/9/14. */ @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface CacheRemove { /** * 需要清除的大类 例如 autocms 所有缓存 * * @return */ String value() default ""; /** * 需要清除的具体的额类型 * * @return */ String[] key() default {}; }
[code]import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.stereotype.Component; import javax.annotation.Resource; import java.lang.reflect.Method; import java.util.Set; /** * 功能描述:清除缓存切面类 * * @author fuyuchao * DATE 2018/9/14. */ @Component @Aspect public class CacheRemoveAspect { Logger logger = LoggerFactory.getLogger(this.getClass()); @Resource(name = "redisTemplate") RedisTemplate<String, String> redis; //截获标有@CacheRemove的方法 @Pointcut(value = "(execution(* *.*(..)) && @annotation(com.yooli.cms.cache.CacheRemove))") private void pointcut() { } /** * 功能描述: 切面在截获方法返回值之后 * * @return void * @throws * @author fuyuchao * @date 2018/9/14 16:55 * @params [joinPoint] */ @AfterReturning(value = "pointcut()") private void process(JoinPoint joinPoint) { //获取被代理的类 Object target = joinPoint.getTarget(); //获取切入方法的数据 MethodSignature signature = (MethodSignature) joinPoint.getSignature(); //获取切入方法 Method method = signature.getMethod(); //获得注解 CacheRemove cacheRemove = method.getAnnotation(CacheRemove.class); if (cacheRemove != null) { //清除当前类的缓存 cleanRedisCache("*" + target.getClass().toString() + "*"); String value = cacheRemove.value(); if (!value.equals("")) { //缓存的项目所有redis业务部缓存 cleanRedisCache("*" + value + "*"); } //需要移除的正则key String[] keys = cacheRemove.key(); for (String key : keys) { //指定清除的key的缓存 cleanRedisCache("*" + key + "*"); } } } private void cleanRedisCache(String key) { if (key != null) { Set<String> stringSet = redis.keys(key); redis.delete(stringSet);//删除缓存 logger.info("清除 " + key + " 缓存"); } } }阅读更多
相关文章推荐
- 8 -- 深入使用Spring -- 5...3 使用@CacheEvict清除缓存
- Spring缓存注解@Cacheable、@CacheEvict、@CachePut使用
- Linux的cached和pagecache清除 解决缓存、内存不足、测试结果影响问题
- win7系统修复本地连接提示“windows无法完成修复问题,需要清除DNS缓存”的解决方法
- Spring缓存注解@CachePut , @CacheEvict,@CacheConfig使用
- 设置windows2008系统缓存大小限制,解决服务器运行久了因物理内存耗尽出僵死(提升权限后,使用SetSystemFileCacheSize API函数,并将此做成了一个Service)
- shiro安全框架扩展教程--异常退出没有清除缓存信息处理方案
- 基于注解的spring缓存,轻松无侵入解决cache问题
- 使用缓存时候,发现Page_load只能运行一次的解决方法。
- SQL模糊查询及扩展正则表达式的使用
- Cache清除缓存数据
- 缓存注解 Cachealble CacheEvict CachePut 浅谈,以及conditions和ulessSpEL表达式
- nginx反向代理,动静态请求分离,以及nginx缓存应用,以及使用ngx_cache_purge清除指定URL
- 需要清除memcach缓存方能解决的几个报错
- Spring缓存注解@Cache,@CachePut , @CacheEvict,@CacheConfig使用
- shiro安全框架扩展教程--异常退出没有清除缓存信息处理方案
- Spring Cache扩展:注解失效时间+主动刷新缓存
- 只能输入数字的正则表达式在火狐的兼容问题解决方法
- 过滤器篇(2)-----过滤器设置编码格式与清除浏览器缓存(EncodingFilter , NoCacheFilter)
- NW中实现清除缓存的解决办法