最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

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

 更新時(shí)間:2018年02月05日 08:56:37   作者:zer0black  
本篇文章主要介紹了ehcache模糊批量移除緩存的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

前言

眾所周知,encache是現(xiàn)在最流行的java開源緩存框架,配置簡(jiǎn)單,結(jié)構(gòu)清晰,功能強(qiáng)大。通過注解 @Cacheable 可以快速添加方法結(jié)果到緩存。通過 @CacheEvict 可以快速清除掉指定的緩存。

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

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

上述代碼是分頁獲取任務(wù)信息。用EL表達(dá)式獲取到參數(shù)中的page,并作為緩存的key,使用 @Cacheable 添加到ehcache的緩存中。此時(shí),在緩存中就會(huì)出現(xiàn) listOfTask_1 , listOfTask_2 , listOfTask_3 這種類型的key。

當(dāng)添加、刪除任務(wù)時(shí),列表就會(huì)發(fā)生改變。這時(shí)候,就需要把 listOfTask_* 相關(guān)的緩存全部去掉。而這時(shí),我不知道緩存中到底緩存了多少和 listOfTask_* 相關(guān)的內(nèi)容,不可能調(diào)用 @CacheEvict 挨個(gè)刪除。

既然ehcache本身無法支持,那就只能靠我們自己實(shí)現(xiàn)了。

實(shí)現(xiàn)

考慮到使用的注解添加的緩存,那么移除緩存也使用注解處理,可以保持開發(fā)的一致性。注解對(duì)開發(fā)者來說也很友好。那么我們就考慮使用自定義注解來來模糊批量移除緩存。

首先,定義注解 CacheRemove :

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

其中,value 同 ehcache 一樣,用于定義要操作的緩存名。key 是一個(gè)數(shù)組,用于存放多種緩存 key 的正則表達(dá)式。起名 CacheRemove 清晰易懂,也不與 ehcache 本身的注解沖突。注解的定義到此為止。接下來,就需要處理注解了,由于使用的 spring 框架,很自然的,就會(huì)想到用 AOP 來做注解的具體實(shí)現(xiàn)。

注解的目的是批量模糊移除緩存。需考慮如下兩個(gè)問題:

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

我給出的處理方式,也是我認(rèn)為最簡(jiǎn)單的處理方式是:

  1. 用什么方式模糊匹配 —— CacheRemove 中的key傳正則,可以傳多個(gè),使用正則匹配
  2. 怎么批量刪除key —— 循環(huán)所有的key,找到匹配正則的就刪除

首先定義類名 CacheRemoveAspect :

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

  do something...
}

在切面中定義切點(diǎn),使用 execution(* *.*(..) && @annotation(com.example.CacheRemove)) 表示所有帶注解類 CacheRemove 都執(zhí)行, @annotation 中的值是注解的全限定名。

切點(diǎn)定義完畢,下面的重頭戲就是切面的具體實(shí)現(xiàn)了。一般來說,緩存會(huì)在增刪改的方法執(zhí)行完后才要移除。所以使用 @AfterReturning() 來實(shí)現(xiàn)。在具體實(shí)現(xiàn)中需要做以下幾件事:

  1. 攔截方法上的注解
  2. 判斷注解是不是 CacheRemove
  3. 由于注解傳入的 key 是個(gè)數(shù)組,循環(huán)處理每個(gè)key
  4. 在循環(huán)中編制每個(gè) key 為 pattern, 并循環(huán)所有的緩存,移除匹配上的緩存

具體實(shí)現(xiàn)如下:

@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 模糊批量移除緩存的具體實(shí)現(xiàn)。其中 BusinessCacheUtils 為自己封裝的 ehcache 工具類。主要實(shí)現(xiàn)獲取緩存池,獲取緩存,移除緩存,添加緩存,查看所有緩存等正常功能。代碼如下:

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();
  }

  /**
   * 獲得一個(gè)Cache,沒有則創(chuàng)建一個(gè)。
   * @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;
  }

}

至此,整個(gè)ehcache 模糊批量移除緩存的功能就實(shí)現(xiàn)了。

總結(jié)

整個(gè)過程思路簡(jiǎn)單,用到了一些 AOP 的知識(shí)就完成了需要的功能。但具體的移除部分代碼可考慮進(jìn)行優(yōu)化。通過一次緩存的全部循環(huán),就把需要移除的緩存都移除干凈,而不是想現(xiàn)在這樣有幾個(gè)key,就全緩存遍歷幾次。具體實(shí)現(xiàn)留給讀者自行完成。希望對(duì)各位有所幫助。也希望大家多多支持腳本之家。

相關(guān)文章

  • 一文掌握MyBatis?Plus的條件構(gòu)造器方法

    一文掌握MyBatis?Plus的條件構(gòu)造器方法

    這篇文章主要介紹了MyBatis?Plus的條件構(gòu)造器,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-02-02
  • mybatis if標(biāo)簽判斷不生效的解決方法

    mybatis if標(biāo)簽判斷不生效的解決方法

    這篇文章主要介紹了mybatis if標(biāo)簽判斷不生效的解決方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-02-02
  • Spring Boot使用線程池創(chuàng)建多線程的完整示例

    Spring Boot使用線程池創(chuàng)建多線程的完整示例

    在 Spring Boot 2 中,可以使用 @Autowired 注入 線程池(ThreadPoolTaskExecutor 或 ExecutorService),從而管理線程的創(chuàng)建和執(zhí)行,以下是使用 @Autowired 方式注入線程池的完整示例,感興趣的朋友一起看看吧
    2025-03-03
  • 詳解全局事務(wù)注解@GlobalTransactional的識(shí)別

    詳解全局事務(wù)注解@GlobalTransactional的識(shí)別

    這篇文章主要為大家介紹了詳解全局事務(wù)注解@GlobalTransactional的識(shí)別源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-12-12
  • java Class文件結(jié)構(gòu)解析常量池字節(jié)碼

    java Class文件結(jié)構(gòu)解析常量池字節(jié)碼

    這篇文章主要為大家介紹了java Class文件的整體結(jié)構(gòu)解析常量池字節(jié)碼詳細(xì)講解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • 相冊(cè)管理系統(tǒng)(Java表單+xml數(shù)據(jù)庫存儲(chǔ))

    相冊(cè)管理系統(tǒng)(Java表單+xml數(shù)據(jù)庫存儲(chǔ))

    這篇文章主要為大家詳細(xì)介紹了相冊(cè)管理系統(tǒng)的實(shí)現(xiàn)步驟,Java表單的文件上傳和下載,xml數(shù)據(jù)庫存儲(chǔ)信息,感興趣的小伙伴們可以參考一下
    2016-07-07
  • vue+ java 實(shí)現(xiàn)多級(jí)菜單遞歸效果

    vue+ java 實(shí)現(xiàn)多級(jí)菜單遞歸效果

    這篇文章主要介紹了vue+ java 實(shí)現(xiàn)多級(jí)菜單遞歸效果,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-12-12
  • MybatisPlus多條件?or()的使用問題小結(jié)

    MybatisPlus多條件?or()的使用問題小結(jié)

    這篇文章主要介紹了MybatisPlus多條件?or()的使用問題小結(jié),本文給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2024-05-05
  • 解決使用this.getClass().getResource()獲取文件時(shí)遇到的坑

    解決使用this.getClass().getResource()獲取文件時(shí)遇到的坑

    這篇文章主要介紹了解決使用this.getClass().getResource()獲取文件時(shí)遇到的坑問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • Java深入淺出理解快速排序以及優(yōu)化方式

    Java深入淺出理解快速排序以及優(yōu)化方式

    快速排序由于排序效率在同為O(N*logN)的幾種排序方法中效率較高,因此經(jīng)常被采用,再加上快速排序思想----分治法也確實(shí)實(shí)用,因此很多軟件公司的筆試面試,包括像騰訊,微軟等知名IT公司都喜歡考這個(gè),還有大大小的程序方面的考試如軟考,考研中也常常出現(xiàn)快速排序的身影
    2021-11-11

最新評(píng)論

洛南县| 宁波市| 芒康县| 辽中县| 麟游县| 龙里县| 阳原县| 兖州市| 拉萨市| 西乌珠穆沁旗| 伊宁县| 沙坪坝区| 调兵山市| 昔阳县| 黄平县| 五家渠市| 永平县| 上饶县| 青铜峡市| 上高县| 洮南市| 阿拉尔市| 天津市| 象州县| 台州市| 汤阴县| 玉树县| 顺义区| 陆河县| 尚志市| 开阳县| 城固县| 河间市| 湘阴县| 卫辉市| 长治市| 滦平县| 湖南省| 上虞市| 平凉市| 霞浦县|