下面由redis教程欄目給大家介紹關于spring redis注解實現緩存機制,希望對需要的朋友有所幫助!
1、xml配置
?<bean>?? ????????<property></property>?? ????????<property></property>?? ????????<property></property> ????????<property></property>?? ????</bean>?? ????<!-- Tax redis 數據庫 --> ????<bean></bean>?? ????<!--redis操作模版,使用該對象可以操作redis -->?? ????<bean>???? ????????<property></property>???? ????????<!--如果不配置Serializer,那么存儲的時候缺省使用String,如果用User類型存儲,那么會提示錯誤User can't cast to String!! -->???? ????????<property>???? ????????????<bean></bean>???? ????????</property>???? ????????<property>???? ????????????<bean></bean>???? ????????</property>???? ????????<property>???? ????????????<bean></bean>???? ????????</property>???? ????????<property>???? ????????????<bean></bean>???? ????????</property>???? ????????<!--開啟事務 -->?? ????????<property></property>?? ????</bean>??? ????<!-- 配置RedisCacheManager --> ????<bean> ????????<constructor-arg></constructor-arg> ????</bean> ????<annotation-driven></annotation-driven>
2、緩存注解@Cacheable、@CacheEvict、@CachePut詳解
一、@Cacheable用法詳解
1、用在哪里?用在方法或者類上。
2、這兩種用法有什么區別?
用在方法上表示:該方法的返回值將被緩存起來?
用在類上表示:表示該類的所有方法都支持該注解
3、使用后的結果是什么?下次使用相同方法和相同參數調用這個方法的時候將直接從緩存取值,而不需要再次執行該方法。
4、返回值在緩存中怎么存儲的?以鍵值對的方式存儲在緩存中,value就是返回值,key由兩種策略生成:默認策略和自定義策略
5、默認策略和默認策略怎么用?
默認策略:在value值后雙“::”拼接,形參列表,當形參是對象時,使用json格式:
@CacheConfig(cacheNames="enterprise")//<!-- 聲明緩存使用的緩存名稱 --> public?interface?EnterpriseRepo?extends?JpaRepository<enterprise>,JpaSpecificationExecutor<enterprise>{ ????@Cacheable(value="cash1") ????Enterprise?findByid(Integer?id); ????@CachePut(value="cash1") ????Enterprise?save(Enterprise?enterprise); }</enterprise></enterprise>
自定義策略: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; ???} ???@Cacheable(value="users",?key="#user.id") ???public?User?find(User?user)?{ ??????return?null; ???} ???@Cacheable(value="users",?key="#p0.id") ???public?User?find(User?user)?{ ??????return?null; ???}
除了上述使用方法參數作為key之外,Spring還為我們提供了一個root對象可以用來生成key。通過該root對象我們可以獲取到以下信息。
當我們要使用root對象的屬性作為key時我們也可以將“#root”省略,因為Spring默認使用的就是root對象的屬性。如:
@Cacheable(value={"users",?"xxx"},?key="caches[1].name") public?User?find(User?user)?{ ???return?null; }
6、condition屬性指定發生的條件
??有的時候我們可能并不希望緩存一個方法所有的返回結果。通過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; }
二、@CachePut
在支持Spring Cache的環境下,對于使用@Cacheable標注的方法,Spring在每次執行前都會檢查Cache中是否存在相同key的緩存元素,如果存在就不再執行該方法,而是直接從緩存中獲取結果進行返回,否則才會執行并將返回結果存入指定的緩存中。@CachePut也可以聲明一個方法支持緩存功能。與@Cacheable不同的是使用@CachePut標注的方法在執行前不會去檢查緩存中是否存在之前執行過的結果,而是每次都會執行該方法,并將執行結果以鍵值對的形式存入指定的緩存中。
? 一般使用在保存,更新方法中。
? ? @CachePut也可以標注在類上和方法上。使用@CachePut時我們可以指定的屬性跟@Cacheable是一樣的。
????@CachePut(“users”)//每次都會執行方法,并將結果存入指定的緩存中
public?User?find(Integer?id)?{ ??????return?null; }
三、@CacheEvict
@CacheEvict是用來標注在需要清除緩存元素的方法或類上的。當標記在一個類上時表示其中所有的方法的執行都會觸發緩存的清除操作。@CacheEvict可以指定的屬性有value、key、condition、allEntries和beforeInvocation。其中value、key和condition的語義與@Cacheable對應的屬性類似。即value表示清除操作是發生在哪些Cache上的(對應Cache的名稱);key表示需要清除的是哪個key,如未指定則會使用默認策略生成的key;condition表示清除操作發生的條件。下面我們來介紹一下新出現的兩個屬性allEntries和beforeInvocation。
1、 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); }
2、beforeInvocation屬性
?清除操作默認是在對應方法成功執行之后觸發的,即方法如果因為拋出異常而未能成功返回時也不會觸發清除操作。使用beforeInvocation可以改變觸發清除操作的時間,當我們指定該屬性值為true時,Spring會在調用該方法之前清除緩存中的指定元素。
@CacheEvict(value="users",?beforeInvocation=true) public?void?delete(Integer?id)?{ ???System.out.println("delete?user?by?id:?"?+?id); }