欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring緩存注解@Cacheable @CacheEvit @CachePut使用介紹

 更新時間:2021年07月05日 10:51:29   作者:一灰灰  
Spring在3.1版本,就提供了一條基于注解的緩存策略,實際使用起來還是很絲滑的,本文將針對幾個常用的注解進行簡單的介紹說明,有需要的小伙伴可以嘗試一下

Spring在3.1版本,就提供了一條基于注解的緩存策略,實際使用起來還是很絲滑的,本文將針對幾個常用的注解進行簡單的介紹說明,有需要的小伙伴可以嘗試一下

本文主要知識點:

  • @Cacheable: 緩存存在,則使用緩存;不存在,則執(zhí)行方法,并將結果塞入緩存
  • @CacheEvit: 失效緩存
  • @CachePut: 更新緩存

I. 項目環(huán)境

1. 項目依賴

本項目借助SpringBoot 2.2.1.RELEASE + maven 3.5.3 + IDEA + redis5.0進行開發(fā)
開一個web服務用于測試

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
</dependencies>

全程使用默認配置,redis本機,端口6379,無密碼

II. 緩存注解介紹

1. @Cacheable

這個注解用于修飾方法or類,當我們訪問它修飾的方法時,優(yōu)先從緩存中獲取,若緩存中存在,則直接獲取緩存的值;緩存不存在時,執(zhí)行方法,并將結果寫入緩存
這個注解,有兩個比較核心的設置

 /**
  * 與 cacheNames 效果等價
  */
 @AliasFor("cacheNames")
 String[] value() default {};

 
 @AliasFor("value")
 String[] cacheNames() default {};

 /**
  * 緩存key
  */
 String key() default "";

cacheNames可以理解為緩存key的前綴,可以為組件緩存的key變量;當key不設置時,使用方法參數(shù)來初始化,注意key為SpEL表達式,因此如果要寫字符串時,用單引號括起來

一個簡單的使用姿勢

/**
 * 首先從緩存中查,查到之后,直接返回緩存數(shù)據(jù);否則執(zhí)行方法,并將結果緩存
 * <p>
 * redisKey: cacheNames + key 組合而成 --> 支持SpEL
 * redisValue: 返回結果
 *
 * @param name
 * @return
 */
@Cacheable(cacheNames = "say", key = "'p_'+ #name")
public String sayHello(String name) {
    return "hello+" + name + "-->" + UUID.randomUUID().toString();
}

如我們傳參為 yihuihui, 那么緩存key為 say::p_yihuihui

除了上面三個配置值之外,查看@Cacheable注解源碼的童鞋可以看到還有condition設置,這個表示當它設置的條件達成時,才寫入緩存

/**
 * 滿足condition條件的才寫入緩存
 *
 * @param age
 * @return
 */
@Cacheable(cacheNames = "condition", key = "#age", condition = "#age % 2 == 0")
public String setByCondition(int age) {
    return "condition:" + age + "-->" + UUID.randomUUID().toString();
}

上面這個case中,age為偶數(shù)的時候,才走緩存;否則不寫緩存
接下來是unless參數(shù),從名字上可以看出它表示不滿足條件時才寫入緩存

/**
 * unless, 不滿足條件才寫入緩存
 *
 * @param age
 * @return
 */
@Cacheable(cacheNames = "unless", key = "#age", unless = "#age % 2 == 0")
public String setUnless(int age) {
    return "unless:" + age + "-->" + UUID.randomUUID().toString();
}

2. @CachePut

不管緩存有沒有,都將方法的返回結果寫入緩存;適用于緩存更新

/**
 * 不管緩存有沒有,都寫入緩存
 *
 * @param age
 * @return
 */
@CachePut(cacheNames = "t4", key = "#age")
public String cachePut(int age) {
    return "t4:" + age + "-->" + UUID.randomUUID().toString();
}

3. @CacheEvict

這個就是我們理解的刪除緩存

/**
 * 失效緩存
 *
 * @param name
 * @return
 */
@CacheEvict(cacheNames = "say", key = "'p_'+ #name")
public String evict(String name) {
    return "evict+" + name + "-->" + UUID.randomUUID().toString();
}

4. @Caching

在實際的工作中,經(jīng)常會遇到一個數(shù)據(jù)變動,更新多個緩存的場景,對于這個場景,可以通過@Caching來實現(xiàn)

/**
 * caching實現(xiàn)組合,添加緩存,并失效其他的緩存
 *
 * @param age
 * @return
 */
@Caching(cacheable = @Cacheable(cacheNames = "caching", key = "#age"), evict = @CacheEvict(cacheNames = "t4", key = "#age"))
public String caching(int age) {
    return "caching: " + age + "-->" + UUID.randomUUID().toString();
}

上面這個就是組合操作

  • 從 caching::age緩存取數(shù)據(jù),不存在時執(zhí)行方法并寫入緩存;
  • 失效緩存 t4::age

5. 異常時,緩存會怎樣?

上面的幾個case,都是正常的場景,當方法拋出異常時,這個緩存表現(xiàn)會怎樣?

/**
 * 用于測試異常時,是否會寫入緩存
 *
 * @param age
 * @return
 */
@Cacheable(cacheNames = "exception", key = "#age")
@Cacheable(cacheNames = "say", key = "'p_yihuihui'")
public int exception(int age) {
    return 10 / age;
}

根據(jù)實測結果,當age==0時,上面兩個緩存都不會成功

6. 測試用例

接下來驗證下緩存注解與上面描述的是否一致

@RestController
public class IndexRest {
    @Autowired
    private BasicDemo helloService;

    @GetMapping(path = {"", "/"})
    public String hello(String name) {
        return helloService.sayHello(name);
    }
}

上面這個主要是驗證@Cacheable注解,若緩存不命中,每次返回的結果應該都不一樣,然而實際訪問時,會發(fā)現(xiàn)返回的都是相同的

curl http://localhost:8080/?name=yihuihui

失效緩存

@GetMapping(path = "evict")
public String evict(String name) {
    return helloService.evict(String.valueOf(name));
}

失效緩存,需要和上面的case配合起來使用

curl http://localhost:8080/evict?name=yihuihui
curl http://localhost:8080/?name=yihuihui

剩下其他的相關測試類就比較好理解了,一并貼出對應的代碼

@GetMapping(path = "condition")
public String t1(int age) {
    return helloService.setByCondition(age);
}

@GetMapping(path = "unless")
public String t2(int age) {
    return helloService.setUnless(age);
}

@GetMapping(path = "exception")
public String exception(int age) {
    try {
        return String.valueOf(helloService.exception(age));
    } catch (Exception e) {
        return e.getMessage();
    }
}

@GetMapping(path = "cachePut")
public String cachePut(int age) {
    return helloService.cachePut(age);
}

7. 小結

最后管理小結一下Spring提供的幾個緩存注解

  • @Cacheable: 緩存存在,則從緩存?。环駝t執(zhí)行方法,并將返回結果寫入緩存
  • @CacheEvit: 失效緩存
  • @CachePut: 更新緩存
  • @Caching: 都注解組合

上面雖說可以滿足常見的緩存使用場景,但是有一個非常重要的點沒有說明,緩存失效時間應該怎么設置???
如何給每個緩存設置不同的緩存失效時間,咱么下篇博文見,我是一灰灰,歡迎關注長草的公眾號一灰灰blog

III. 不能錯過的源碼和相關知識點

0. 項目

工程:https://github.com/liuyueyi/spring-boot-demo
源碼:https://github.com/liuyueyi/spring-boot-demo/tree/master/spring-boot/125-cache-ano

到此這篇關于Spring緩存注解@Cacheable @CacheEvit @CachePut使用介紹的文章就介紹到這了,更多相關Spring @Cacheable @CacheEvit @CachePut內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 淺談Java編程ToString()方法重寫的意義

    淺談Java編程ToString()方法重寫的意義

    這篇文章主要介紹了淺談Java編程ToString()方法重寫的意義,還是挺不錯的,這里分享給大家,供朋友們學習和參考。
    2017-10-10
  • JDK1.7的ConcurrentHashMap源碼解析

    JDK1.7的ConcurrentHashMap源碼解析

    這篇文章主要介紹了JDK1.7的ConcurrentHashMap源碼解析,HashMap是非線程安全的,而HashTable是線程安全的,但是HashTable實現(xiàn)同步的方法比較暴力,即在所有的方法體上添加synchronized關鍵字,需要的朋友可以參考下
    2023-12-12
  • 使用Java Servlet生成動態(tài)二維碼的實現(xiàn)步驟

    使用Java Servlet生成動態(tài)二維碼的實現(xiàn)步驟

    在現(xiàn)代互聯(lián)網(wǎng)時代,二維碼廣泛應用于各個領域,包括支付、認證、信息傳遞等,在Web開發(fā)中,通過Java Servlet生成動態(tài)二維碼是一個常見的需求,本文將介紹如何使用Java Servlet結合Google的ZXing庫生成動態(tài)二維碼,需要的朋友可以參考下
    2023-11-11
  • Spring-Boot 訪問外部接口的方案總結

    Spring-Boot 訪問外部接口的方案總結

    在Spring-Boot項目開發(fā)中,存在著本模塊的代碼需要訪問外面模塊接口,或外部url鏈接的需求,針對這一需求目前存在著三種解決方案,下面將對這三種方案進行整理和說明,對Spring-Boot 訪問外部接口方案感興趣的朋友跟隨小編一起看看吧
    2022-12-12
  • Maven里面沒有plugins dependence問題解決

    Maven里面沒有plugins dependence問題解決

    在整合Nacos和Dubbo時,出現(xiàn)Maven錯誤可以通過檢查父模塊的依賴解決,問題源于MySQL驅動版本不兼容,移除特定依賴并刷新pom文件可恢復項目,執(zhí)行clean命令,查看報錯,感興趣的可以了解一下
    2024-10-10
  • Java實現(xiàn)批量發(fā)送帶附件的郵件代碼

    Java實現(xiàn)批量發(fā)送帶附件的郵件代碼

    大家好,本篇文章主要講的是Java實現(xiàn)批量發(fā)送帶附件的郵件代碼,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2022-01-01
  • 關于Controller 層返回值的公共包裝類的問題

    關于Controller 層返回值的公共包裝類的問題

    本文給大家介紹Controller 層返回值的公共包裝類-避免每次都包裝一次返回-InitializingBean增強,本文通過實例代碼給大家介紹的非常詳細,需要的朋友參考下吧
    2021-09-09
  • Java多維數(shù)組詳解

    Java多維數(shù)組詳解

    大家好,本篇文章主要講的是Java多維數(shù)組詳解,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • RabbitMQ使用案例詳解

    RabbitMQ使用案例詳解

    RabbitMQ是基于Erlang語言開發(fā)的開源的消息中間件,這篇文章給大家介紹RabbitMQ使用案例,感興趣的朋友跟隨小編一起看看吧
    2024-03-03
  • Mybatis SQL日志如何轉換為可執(zhí)行sql

    Mybatis SQL日志如何轉換為可執(zhí)行sql

    這篇文章主要介紹了Mybatis SQL日志如何轉換為可執(zhí)行sql問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-09-09

最新評論