您的位置:首页 > 其它

@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 + " 缓存");
}
}
}

参考:https://www.geek-share.com/detail/2728726160.html

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐