目录

前言

众所周知,encache是现在最流行的java开源缓存框架,配置简单,结构清晰,功能强大。通过注解@Cacheable可以快速添加方法结果到缓存。通过@CacheEvict可以快速清除掉指定的缓存。

但由于@CacheEvict注解使用的是key-value的,不支持模糊删除,就会遇到问题。当我用@Cacheable配合Spring EL表达式添加了同一方法的多个缓存比如:

@GetMapping("/listOfTask/{page}/")
@Cacheable(value = "BusinessCache", key = "'listOfTask_'+ #page")
public ResponseMessage<PageTaskVO> getTaskList(@PathVariable("page") String page) {
do something...
}

上述代码是分页获取任务信息。用EL表达式获取到参数中的page,并作为缓存的key,使用@Cacheable添加到ehcache的缓存中。此时,在缓存中就会出现listOfTask_1, listOfTask_2, listOfTask_3这种类型的key。

当添加、删除任务时,列表就会发生改变。这时候,就需要把listOfTask_*相关的缓存全部去掉。而这时,我不知道缓存中到底缓存了多少和listOfTask_*相关的内容,不可能调用@CacheEvict挨个删除。

既然ehcache本身无法支持,那就只能靠我们自己实现了。

实现

考虑到使用的注解添加的缓存,那么移除缓存也使用注解处理,可以保持开发的一致性。注解对开发者来说也很友好。那么我们就考虑使用自定义注解来来模糊批量移除缓存。

首先,定义注解CacheRemove

@Target({ java.lang.annotation.ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface CacheRemove {
String value();
String[] key();
}

其中,value 同 ehcache 一样,用于定义要操作的缓存名。key 是一个数组,用于存放多种缓存 key 的正则表达式。起名 CacheRemove 清晰易懂,也不与 ehcache 本身的注解冲突。注解的定义到此为止。接下来,就需要处理注解了,由于使用的 spring 框架,很自然的,就会想到用 AOP 来做注解的具体实现。

注解的目的是批量模糊移除缓存。需考虑如下两个问题:

  1. 用什么方式模糊匹配
  2. 怎么批量删除key

我给出的处理方式,也是我认为最简单的处理方式是:

  1. 用什么方式模糊匹配 —— CacheRemove中的key传正则,可以传多个,使用正则匹配
  2. 怎么批量删除key —— 循环所有的key,找到匹配正则的就删除

首先定义类名CacheRemoveAspect

@Aspect
@Component
public class CacheRemoveAspect {
@Pointcut(value = "(execution(* *.*(..)) && @annotation(com.example.CacheRemove))")
private void pointcut() {} do something...
}

在切面中定义切点,使用execution(* *.*(..) && @annotation(com.example.CacheRemove))表示所有带注解类CacheRemove都执行,@annotation中的值是注解的全限定名。

切点定义完毕,下面的重头戏就是切面的具体实现了。一般来说,缓存会在增删改的方法执行完后才要移除。所以使用@AfterReturning()来实现。在具体实现中需要做以下几件事:

  1. 拦截方法上的注解
  2. 判断注解是不是CacheRemove
  3. 由于注解传入的 key 是个数组,循环处理每个key
  4. 在循环中编制每个 key 为 pattern, 并循环所有的缓存,移除匹配上的缓存

具体实现如下:

@AfterReturning(value = "pointcut()")
private void process(JoinPoint joinPoint){
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
CacheRemove cacheRemove = method.getAnnotation(CacheRemove.class); if (cacheRemove != null){
String value = cacheRemove.value();
String[] keys = cacheRemove.key(); //需要移除的正则key List cacheKeys = CacheUtils.cacheKeys(value);
for (String key : keys){
Pattern pattern = Pattern.compile(key);
for (Object cacheKey: cacheKeys) {
String cacheKeyStr = String.valueOf(cacheKey);
if (pattern.matcher(cacheKeyStr).find()){
CacheUtils.remove(value, cacheKeyStr);
}
}
}
}
}

以上,为 ehcache 模糊批量移除缓存的具体实现。其中 BusinessCacheUtils 为自己封装的 ehcache 工具类。主要实现获取缓存池,获取缓存,移除缓存,添加缓存,查看所有缓存等正常功能。代码如下:

public class CacheUtils {

    private static CacheManager cacheManager = SpringContextHolder.getBean("ehCacheManagerFactory");

    public static Object get(String cacheName, String key) {
Element element = getCache(cacheName).get(key);
return element == null ? null : element.getObjectValue();
} public static void put(String cacheName, String key, Object value) {
Element element = new Element(key, value);
getCache(cacheName).put(element);
} public static void remove(String cacheName, String key) {
getCache(cacheName).remove(key);
} public static List cacheKeys(String cacheName){
return getCache(cacheName).getKeys();
} /**
* 获得一个Cache,没有则创建一个。
* @param cacheName
* @return
*/
private static Cache getCache(String cacheName) {
Cache cache = cacheManager.getCache(cacheName);
if (cache == null) {
cacheManager.addCache(cacheName);
cache = cacheManager.getCache(cacheName);
cache.getCacheConfiguration().setEternal(true);
}
return cache;
} public static CacheManager getCacheManager() {
return cacheManager;
} }

至此,整个ehcache 模糊批量移除缓存的功能就实现了。

总结

整个过程思路简单,用到了一些 AOP 的知识就完成了需要的功能。但具体的移除部分代码可考虑进行优化。通过一次缓存的全部循环,就把需要移除的缓存都移除干净,而不是想现在这样有几个key,就全缓存遍历几次。具体实现留给读者自行完成。希望对各位有所帮助。

ehcache模糊批量移除缓存的更多相关文章

  1. 7.4mybatis整合ehcache(mybatis无法实现分布式缓存必须和其他缓存框架整合)

    <\mybatis\day02\14查询缓存-二级缓存-整合ehcache.av> mybatis的缓存机制(一级缓存二级缓存和刷新缓存)和mybatis整合ehcache-- 这里有做本 ...

  2. 使用Spring提供的缓存抽象机制整合EHCache为项目提供二级缓存

      Spring自身并没有实现缓存解决方案,但是对缓存管理功能提供了声明式的支持,能够与多种流行的缓存实现进行集成. Spring Cache是作用在方法上的(不能理解为只注解在方法上),其核心思想是 ...

  3. 【Ehcache】ehcache2.5.2缓存的使用

    缓存的名字是ehcache...老是记得是encache.... 官方PDF文档:http://www.ehcache.org/documentation/ehcache-2.5.x-document ...

  4. 使用正则表达式在VS中批量移除 try-catch

    使用正则表达式在VS中批量移除 try-catch 前言 try-catch 意为捕获错误,一般在可能出错的地方使用(如调用外部函数或外部设备),以对错误进行正确的处理,并进行后续操作而不至于程序直接 ...

  5. EF批量操作数据与缓存扩展框架

    前言 在原生的EF框架中,针对批量数据操作的接口有限,EF扩展框架弥补了EF在批量操作时的接口,这些批量操作包括:批量修改.批量查询.批量删除和数据缓存,如果您想在EF中更方便的批量操作数据,这个扩展 ...

  6. Ehcache(04)——设置缓存的大小

    http://haohaoxuexi.iteye.com/blog/2116749 设置缓存的大小 目录 1     CacheManager级别 2     Cache级别 3     大小衡量 4 ...

  7. 批量更新memcached缓存

    假如系统里有3类数据company,user,product 利用维护版本号version的方式达到批量更新缓存的效果 memcache.Add("company",cversio ...

  8. 玩转EhCache之最简单的缓存框架

    二.主要特性 快速: 简单: 多种缓存策略: 缓存数据有两级:内存和磁盘,因此无需担心容量问题: 缓存数据会在虚拟机重启的过程中写入磁盘: 可以通过 RMI.可插入 API 等方式进行分布式缓存: 具 ...

  9. PHP批量清理MIP-cache缓存(内附在线mipcache清理工具)

    MIP是什么?我就不多说了把. MIPCache 又是什么? 科普一下:MIPCache 是一套基于代理的 CDN 缓存系统.可用于缓存所有被某度相关页面引用或者从百度相关服务点出的 MIP 页面.当 ...

随机推荐

  1. 【转载】从头编写 asp.net core 2.0 web api 基础框架 (4) EF配置

    Github源码地址:https://github.com/solenovex/Building-asp.net-core-2-web-api-starter-template-from-scratc ...

  2. Java压测之四两拨千斤

    压测之四两拨千斤核心观念: 1.传统的http请求肯定不能用于压测,原因是请求一次,响应一次,而响应数据同时占用了客户端的带宽,故此,客户端请求后,不需要接受响应,让服务器单相思去. 2.寻找可以令服 ...

  3. Luogu P1231 教辅的组成

    Luogu P1231 教辅的组成 题目背景 滚粗了的HansBug在收拾旧语文书,然而他发现了什么奇妙的东西. 题目描述 蒟蒻HansBug在一本语文书里面发现了一本答案,然而他却明明记得这书应该还 ...

  4. 网络端口地址转换的NAPT配置

    背景:只有一个IP地址,实现内网内多台主机访问外网 原理:NAPT使用不同的端口来映射对各内网的IP地址到一个指定的外网IP地址,多对一. NAPT采用端口多路复用的方式.内部网络的所有主机均可共享一 ...

  5. 【margin和padding的区别】

    margin和padding的区别 margin是指从自身边框到另一个容器边框之间的距离,就是容器外距离.(外边距) padding是指自身边框到自身内部另一个容器边框之间的距离,就是容器内距离.(内 ...

  6. deeplearning.ai 作业中的Python常用命令

    1. print大法 test = Hello World print ("test:" + test) 2. math和numpy的区别:math只对单个元素,numpy会bro ...

  7. 学习web前端技术的笔记,仅供自己查阅备忘,图片上传预览

    <!DOCTYPE html><html><head lang="en"> <meta charset="UTF-8" ...

  8. 【经验分享】Hydra(爆破神器)使用方法

    这个也是backtrack下面很受欢迎的一个工具 参数详解:-R 根据上一次进度继续破解-S 使用SSL协议连接-s 指定端口-l 指定用户名-L 指定用户名字典(文件)-p 指定密码破解-P 指定密 ...

  9. bzoj:1299: [LLH邀请赛]巧克力棒

    原题:http://www.lydsy.com/JudgeOnline/problem.php?id=1299 众多dalao的题解已经很详细了:http://blog.csdn.net/wzq_qw ...

  10. kafka数据迁移实践

    欢迎大家前往云+社区,获取更多腾讯海量技术实践干货哦~ 作者:mikealzhou 本文重点介绍kafka的两类常见数据迁移方式:1.broker内部不同数据盘之间的分区数据迁移:2.不同broker ...