javascript
详解Spring Boot 2.X使用缓存@Cacheable代码示例
從3.1開始,Spring引入了對Cache的支持。其使用方法和原理都類似于Spring對事務管理的支持。Spring Cache是作用在方法上的,其核心思想是這樣的:當我們在調用一個緩存方法時會把該方法參數和返回結果作為一個鍵值對存放在緩存中,等到下次利用同樣的參數來調用該方法時將不再執行該方法,而是直接從緩存中獲取結果進行返回。所以在使用Spring Cache的時候我們要保證我們緩存的方法對于相同的方法參數要有相同的返回結果。
???????使用Spring Cache需要我們做兩方面的事:
???????????1.聲明某些方法使用緩存
???????????2. 配置Spring對Cache的支持
???????和Spring對事務管理的支持一樣,Spring對Cache的支持也有基于注解和基于XML配置兩種方式。下面我們先來看看基于注解的方式。
?
1 基于注解的支持
???????Spring為我們提供了幾個注解來支持Spring Cache。其核心主要是@Cacheable和@CacheEvict。使用@Cacheable標記的方法在執行后Spring Cache將緩存其返回結果,而使用@CacheEvict標記的方法會在方法執行前或者執行后移除Spring Cache中的某些元素。下面我們將來詳細介紹一下Spring基于注解對Cache的支持所提供的幾個注解。
1.1 ???@Cacheable
???????@Cacheable可以標記在一個方法上,也可以標記在一個類上。當標記在一個方法上時表示該方法是支持緩存的,當標記在一個類上時則表示該類所有的方法都是支持緩存的。對于一個支持緩存的方法,Spring會在其被調用后將其返回值緩存起來,以保證下次利用同樣的參數來執行該方法時可以直接從緩存中獲取結果,而不需要再次執行該方法。Spring在緩存方法的返回值時是以鍵值對進行緩存的,值就是方法的返回結果,至于鍵的話,Spring又支持兩種策略,默認策略和自定義策略,這個稍后會進行說明。需要注意的是當一個支持緩存的方法在對象內部被調用時是不會觸發緩存功能的。@Cacheable可以指定三個屬性,value、key和condition。
1.1.1 ?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;}?1.1.2 ?使用key屬性自定義key
???????key屬性是用來指定Spring緩存方法的返回結果時對應的key的。該屬性支持SpringEL表達式。當我們沒有指定該屬性時,Spring將使用默認策略生成key。我們這里先來看看自定義策略,至于默認策略會在后文單獨介紹。
???????自定義策略是指我們可以通過Spring的EL表達式來指定我們的key。這里的EL表達式可以使用方法參數及它們對應的屬性。使用方法參數時我們可以直接使用“#參數名”或者“#p參數index”。下面是幾個使用參數作為key的示例。
除了上述使用方法參數作為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;}1.1.3 ?condition屬性指定發生的條件
有的時候我們可能并不希望緩存一個方法所有的返回結果。通過condition屬性可以實現這一功能。condition屬性默認為空,表示將緩存所有的調用情形。其值是通過SpringEL表達式來指定的,當為true時表示進行緩存處理;當為false時表示不進行緩存處理,即每次調用該方法時該方法都會執行一次。如下示例表示只有當user的id為偶數時才會進行緩存。
1.2 ????@CachePut
???????在支持Spring Cache的環境下,對于使用@Cacheable標注的方法,Spring在每次執行前都會檢查Cache中是否存在相同key的緩存元素,如果存在就不再執行該方法,而是直接從緩存中獲取結果進行返回,否則才會執行并將返回結果存入指定的緩存中。@CachePut也可以聲明一個方法支持緩存功能。與@Cacheable不同的是使用@CachePut標注的方法在執行前不會去檢查緩存中是否存在之前執行過的結果,而是每次都會執行該方法,并將執行結果以鍵值對的形式存入指定的緩存中。
1.3 ????@CacheEvict
???????@CacheEvict是用來標注在需要清除緩存元素的方法或類上的。當標記在一個類上時表示其中所有的方法的執行都會觸發緩存的清除操作。@CacheEvict可以指定的屬性有value、key、condition、allEntries和beforeInvocation。其中value、key和condition的語義與@Cacheable對應的屬性類似。即value表示清除操作是發生在哪些Cache上的(對應Cache的名稱);key表示需要清除的是哪個key,如未指定則會使用默認策略生成的key;condition表示清除操作發生的條件。下面我們來介紹一下新出現的兩個屬性allEntries和beforeInvocation。
1.3.1 ?allEntries屬性
??????allEntries是boolean類型,表示是否需要清除緩存中的所有元素。默認為false,表示不需要。當指定了allEntries為true時,Spring Cache將忽略指定的key。有的時候我們需要Cache一下清除所有的元素,這比一個一個清除元素更有效率。
1.3.2 ?beforeInvocation屬性
???????清除操作默認是在對應方法成功執行之后觸發的,即方法如果因為拋出異常而未能成功返回時也不會觸發清除操作。使用beforeInvocation可以改變觸發清除操作的時間,當我們指定該屬性值為true時,Spring會在調用該方法之前清除緩存中的指定元素。
?其實除了使用@CacheEvict清除緩存元素外,當我們使用Ehcache作為實現時,我們也可以配置Ehcache自身的驅除策略,其是通過Ehcache的配置文件來指定的。由于Ehcache不是本文描述的重點,這里就不多贅述了,想了解更多關于Ehcache的信息,請查看我關于Ehcache的專欄。
?
1.4 ????@Caching
???????@Caching注解可以讓我們在一個方法或者類上同時指定多個Spring Cache相關的注解。其擁有三個屬性:cacheable、put和evict,分別用于指定@Cacheable、@CachePut和@CacheEvict。
1.5 ? ? 使用自定義注解
? ? ? ?Spring允許我們在配置可緩存的方法時使用自定義的注解,前提是自定義的注解上必須使用對應的注解進行標注。如我們有如下這么一個使用@Cacheable進行標注的自定義注解。
@Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Cacheable(value="users") public @interface MyCacheable { }那么在我們需要緩存的方法上使用@MyCacheable進行標注也可以達到同樣的效果。
@MyCacheablepublic 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;}?
總結
以上是生活随笔為你收集整理的详解Spring Boot 2.X使用缓存@Cacheable代码示例的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring Boot 2.X 使用@C
- 下一篇: Spring Boot自定义缓存注解