日本免费高清视频-国产福利视频导航-黄色在线播放国产-天天操天天操天天操天天操|www.shdianci.com

學無先后,達者為師

網站首頁 編程語言 正文

SpringBoot緩存注解@Cacheable、@CacheEvict和@CachePut

作者:忘末nzj 更新時間: 2024-04-08 編程語言

一、簡述

從 3.1 開始,Spring 引入了對 Cache 的支持。其使用方法和原理都類似于 Spring 對事務管理的支持。Spring Cache 是作用在方法上的,其核心思想:當調用一個緩存方法時,會把該方法參數和返回結果作為一個鍵值對存放在緩存中,等到下次利用同樣的參數來調用該方法時將不再執行該方法,而是直接從緩存中獲取結果進行返回。所以在使用 Spring Cache 的時候,要保證緩存的方法對于相同的方法參數要有相同的返回結果。使用 Spring Cache 需要做到兩點:

1??在 Springboot 的啟動類上使用 @EnableCaching 開啟緩存。
2??聲明某些方法使用緩存。

和 Spring 對事務管理的支持一樣,Spring 對 Cache 的支持也有基于注解和基于 XML 配置兩種方式。

二、基于注解的支持

其核心主要是 @Cacheable 和 @CacheEvict。使用 @Cacheable 標記的方法在執行后,Spring Cache 將緩存其返回結果,而使用 @CacheEvict 標記的方法會在方法執行前或者執行后移除 Spring Cache 中的某些元素。

1??@Cacheable:可以標記在類上或者方法上。
當標記在方法上時表示該方法是支持緩存的,當標記在類上時則表示該類所有的方法都是支持緩存的。對于一個支持緩存的方法,Spring 會在其被調用后將其返回值緩存起來,以保證下次利用同樣的參數來執行該方法時可以直接從緩存中獲取結果,而不需要再次執行該方法。Spring 在緩存方法的返回值時是以鍵值對進行緩存的,值就是方法的返回結果,至于鍵的話,Spring 又支持兩種策略,默認策略和自定義策略。需要注意的是當一個支持緩存的方法在對象內部被調用時是不會觸發緩存功能的。@Cacheable 可以指定三個屬性,value、key 和 condition。

【value 屬性指定 Cache 名稱】
value 是必須指定的,其表示當前方法的返回值被緩存在哪個 Cache 上,對應 Cache 的名稱。其可以是一個 Cache 也可以是多個 Cache,當需要指定多個 Cache 時其是一個數組。

@Cacheable("cache1")//Cache是發生在cache1上的
public User find(Integer id) {
    return null;
}
@Cacheable({"cache1", "cache2"})//Cache是發生在cache1和cache2上的
public User find(Integer id) {
    return null;
}

【使用 key 屬性自定義 key】
key 屬性是用來指定 Spring 緩存方法的返回結果時對應的 key 的。該屬性支持 SpringEL 表達式。當沒有指定該屬性時,Spring 將使用默認策略生成 key。
自定義策略是指可以通過 Spring 的 EL 表達式來指定 key。這里的 EL 表達式可以使用方法參數及它們對應的屬性。使用方法參數時可以直接使用#參數名或者#p參數index。如下:

//key是指傳入時的參數
@Cacheable(value="users", key="#id")
public User find(Integer id) {
    return null;
}
// 表示第一個參數
@Cacheable(value="users", key="#p0")
public User find(Integer id) {
    return null;
}
// 表示User中的id值
@Cacheable(value="users", key="#user.id")
public User find(User user) {
    return null;
}
// 表示第一個參數里的id屬性值
@Cacheable(value="users", key="#p0.id")
public User find(User user) {
   return null;
}

除了上述使用方法參數作為 key 之外,Spring 還提供了一個 root 對象可以用來生成 key。通過該 root 對象可以獲取到以下信息。當要使用 root 對象的屬性作為 key 時,也可以將“#root”省略,因為 Spring 默認使用的就是 root 對象的屬性。如:

// key值為:user中的name屬性的值
@Cacheable(value={"users", "xxx"}, key="caches[1].name")
public User find(User user) {
    return null;
}

【condition 屬性指定發生的條件】
有時候可能并不希望緩存一個方法的所有返回結果。condition 屬性默認為空,表示將緩存所有的調用情形。其值是通過 SpringEL 表達式來指定的,當為 true 時表示進行緩存處理;當為 false 時表示不進行緩存處理,即每次調用該方法時該方法都會執行一次。如下表示只有當 user 的 id 為偶數時才會緩存:

// 根據條件判斷是否緩存
@Cacheable(value={"users"}, key="#user.id", condition="#user.id%2==0")
public User find(User user) {
   System.out.println("find user by user " + user);
   return user;
}

2??@CachePut
在支持 Spring Cache 的環境下,對于使用 @Cacheable 標注的方法,Spring 在每次執行前都會檢查 Cache 中是否存在相同 key 的緩存元素,如果存在就不再執行該方法,而是直接從緩存中獲取結果進行返回,否則才會執行并將返回結果存入指定的緩存中。@CachePut 也可以聲明一個方法支持緩存功能。與 @Cacheable 不同的是使用 @CachePut 標注的方法在執行前不會去檢查緩存中是否存在之前執行過的結果,而是每次都會執行該方法,并將執行結果以鍵值對的形式存入指定的緩存中。

//@CachePut也可以標注在類或方法上??梢灾付ǖ膶傩愿鶣Cacheable是一樣的
@CachePut("users")//每次都會執行方法,并將結果存入指定的緩存中
public User find(Integer id) {
   return null;
}

3??@CacheEvict
@CacheEvict 是用來標注在需要清除緩存元素的方法或類上的。當標記在一個類上時表示其中所有的方法的執行都會觸發緩存的清除操作。@CacheEvict 可以指定的屬性有 value、key、condition、allEntries 和 beforeInvocation。其中 value、key 和 condition 的語義與 @Cacheable 對應的屬性類似。即 value 表示清除操作是發生在哪些 Cache 上的(對應 Cache 的名稱);key 表示需要清除的是哪個 key,如未指定則會使用默認策略生成的 key;condition 表示清除操作發生的條件。
【allEntries 屬性】
allEntries 是 boolean 類型,表示是否需要清除緩存中的所有元素。默認為 false,表示不需要。當指定了 allEntries 為 true 時,Spring Cache 將忽略指定的 key。有的時候需要 Cache 一下清除所有的元素,這比一個一個清除元素更有效率。

@CacheEvict(value="users", allEntries=true)
public void delete(Integer id) {
   System.out.println("delete user by id: " + id);
}

【beforeInvocation 屬性】
清除操作默認是在對應方法成功執行之后觸發的,如果方法拋出異常而未能成功返回時不會觸發清除操作。使用 beforeInvocation 可以改變觸發清除操作的時間,當指定該屬性值為 true 時,Spring 會在調用該方法之前清除緩存中的指定元素。

@CacheEvict(value="users", beforeInvocation=true)
public void delete(Integer id) {
   System.out.println("delete user by id: " + id);
}

其實除了使用 @CacheEvict 清除緩存元素外,當使用 Ehcache 作為實現時,也可以配置 Ehcache 自身的清除策略,其是通過 Ehcache 的配置文件來指定的。

4??@Caching
@Caching 注解可以在一個方法或者類上同時指定多個 Spring Cache 相關的注解。其擁有三個屬性:cacheable、put 和 evict,分別用于指定 @Cacheable、@CachePut 和 @CacheEvict。

@Caching(cacheable = @Cacheable("users"), evict = { @CacheEvict("cache2"),
@CacheEvict(value = "cache3", allEntries = true) })
public User find(Integer id) {
   return null;
}

5??使用自定義注解
Spring 允許在配置可緩存的方法時使用自定義的注解,前提是自定義的注解上必須使用對應的注解進行標注。如有如下這么一個使用 @Cacheable 進行標注的自定義注解:

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Cacheable(value="users")
public @interface MyCacheable {
}

那么在需要緩存的方法上使用 @MyCacheable 進行標注也可以達到同樣的效果。

@MyCacheable
public User findById(Integer id) {
    System.out.println("find user by id: " + id);
    User user = new User();
    user.setId(id);
    user.setName("Name" + id);
    return user;
}

三、應用場景

1??@CachePut:更新數據庫的數據并更新緩存

  1. 先調用更新數據庫方法
  2. 再將更新的數據寫入名為(users)緩存中
@PostMapping(value = "/updateUserInfo")
@CachePut(value = "users", key = "#user.userId")
public void updateUserInfo(User user) {
   userService.updateUserInfo(user);
}

2??@Cacheable:查詢出的數據是最新的而不是之前緩存中的

  1. 這里 value 屬性的值同 @CachePut 時的 value 值一樣,確保查詢與更新都是同一塊緩存。
  2. 此時查詢的 key 要和更新的 key 保持一致,確保拿到的是更新后的數據。
@GetMapping(value = "/queryUserInfo/{userId}")
@Cacheable(value = "users", key = "#userId")
public User queryUserInfo(@PathVariable("userId")Integer userId) {
   userService.queryUserInfo(userId);
}

原文鏈接:https://blog.csdn.net/m0_72252418/article/details/137208819

  • 上一篇:沒有了
  • 下一篇:沒有了
欄目分類
最近更新