激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

香港云服务器
服務器之家 - 編程語言 - Java教程 - ehcache模糊批量移除緩存的方法

ehcache模糊批量移除緩存的方法

2021-03-31 13:25zer0black Java教程

本篇文章主要介紹了ehcache模糊批量移除緩存的方法,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧

前言

眾所周知,encache是現在最流行的java開源緩存框架,配置簡單,結構清晰,功能強大。通過注解 @Cacheable 可以快速添加方法結果到緩存。通過 @CacheEvict 可以快速清除掉指定的緩存。

但由于 @CacheEvict 注解使用的是key-value的,不支持模糊刪除,就會遇到問題。當我用 @Cacheable 配合Spring EL表達式添加了同一方法的多個緩存比如:

?
1
2
3
4
5
@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 :

?
1
2
3
4
5
6
@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 :

?
1
2
3
4
5
6
7
8
@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, 并循環所有的緩存,移除匹配上的緩存

具體實現如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@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 工具類。主要實現獲取緩存池,獲取緩存,移除緩存,添加緩存,查看所有緩存等正常功能。代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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,就全緩存遍歷幾次。具體實現留給讀者自行完成。希望對各位有所幫助。也希望大家多多支持服務器之家。

原文鏈接:http://www.cnblogs.com/zer0Black/p/8410984.html

延伸 · 閱讀

精彩推薦
544
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25
主站蜘蛛池模板: 久久精品国产99久久久古代 | av电影网在线观看 | 在线免费日韩 | 欧美3p激情一区二区三区猛视频 | 久久久久久久国产视频 | h视频免费看| 日韩av电影免费在线观看 | 黄色特级一级片 | 久久国产精品一区 | av视在线| 久久亚洲成人 | 成年免费看 | 在线中文字幕观看 | 91看片入口 | 久久精品99国产国产精 | 龙床上的呻吟高h | 91看片在线观看视频 | 97超级碰碰人国产在线观看 | 在线看91 | 九九午夜视频 | 精精国产xxxx视频在线野外 | 欧美日韩网站在线观看 | 国产成人精品自拍视频 | 国产精品99久久久久久久vr | 蜜桃视频在线免费播放 | 日本一区二区三区精品 | 亚洲欧美爱爱 | 亚洲极色| 久久久久久亚洲综合影院红桃 | 美女黄网站免费观看 | 久久亚洲视频网 | 一区二区久久久久草草 | 久久久aa | 精品国产一区二区三区在线 | 在线播放的av网站 | 黄色大片网站在线观看 | 亚州成人在线观看 | 久久久久二区 | 国产午夜精品久久久久久久蜜臀 | 亚洲精品一区二区三区在线看 | 国产三级精品最新在线 |