1. 程式人生 > >springboot番外之spring cache

springboot番外之spring cache

Spring Cache

Spring Cache使用方法與Spring對事務管理的配置相似。Spring Cache的核心就是對某個方法進行快取,其實質就是快取該方法的返回結果,並把方法引數和結果用鍵值對的方式存放到快取中,當再次呼叫該方法使用相應的引數時,就會直接從快取裡面取出指定的結果進行返回。所以在使用Cache的時候我們要保證我們快取的方法對於相同的引數要有相同的返回結果。 -----------Spring對Cache的支援有兩種方法: 1.基於註解的配置 2.基礎XML配置
-----------------------------------------------------通過註解去使用到Cache------------------------------------------
@Cacheable-------使用這個註解的方法在執行後會快取其返回結果。 @CacheEvict--------使用這個註解的方法在其執行前或執行後移除Spring Cache中的某些元素。
[email protected]------------- @Cacheable可以註解在方法上也可以註解在類上。
當標記在方法上面時,表示該方法是可以快取的;
如果標記在類上面,則表示該類的所有方法都是可以快取的。 對於一個支援快取的方法,在執行後,會將其返回結果進行快取起來,以保證下次同樣引數來執行該方法的時候可以從快取中返回結果,而不需要再次執行此方法。Spring快取方法的返回值是以鍵值對進行儲存的,值就是返回結果,鍵的話Spring支援兩種策略,一種是預設策略,一種是自定義策略。
注意:一個支援快取的方法,在物件內部被呼叫是不會觸發快取功能的。 @Cacheable可以指定三個屬性:value、key、condition。 ----------------------value:指定Cache的名稱 value值是必須指定的,其表示該方法快取的返回結果是被快取在哪個Cache上的,對應Cache的名稱。其可以是一個Cache也可以使多個Cache(陣列);
  1. @Cache(value="Cx")//Cache是指定在Cx上面的  或者指定多個@Cache(value={"Cx","Cx1"})
      
  2. public User getUser(String id){  
  3.     return .....;  
  4. }  
-----------------------key:自定義key key屬性是用來指定Spring快取方法返回結果時所對應的key值的。該屬性支援EL表示式。當我們沒有指定key時,Spring會使用預設策略生成key。· -----------key的自定義策略: 自定義策略是表示我們通過EL表示式來指定我們的key。這裡EL表示式可以使用方法引數以及他們對應的屬性。使用方法引數時,我們可以使用“#引數名”。
  1. @Cacheable(value="users", key="#id")  
  2. public User find(Integer id) {  
  3.      returnnull;  
  4. }  
  1. @Cacheable(value="users", key="#user.id")  
  2. public User find(User user) {  
  3.     returnnull;  
  4. }  
除了上面使用方法引數作為Key以外,Spring還為我們提供了一個root物件可以生成key。通過root物件我們還可以獲取到 -------1.methodName  當前方法名    #root.methodName -------2.method       當前方法 #root.method.name -------3.target   當前被動用物件#root.target -------4.targetClass      當前被呼叫物件Class#root.targetClass -------5.args    當前方法引數組成的陣列#root.args[0] -------6.caches    當前被呼叫方法所使用的Cache#root.caches[0],name 當我們要使用root作為key時,可以不用寫root直接@Cache(key="caches[1].name")。因為他預設是使用#root的
-----------------condition:指定發生條件 有時候可能不需要快取一個方法的所有結果。通過condition可以設定一個條件,其條件值是使用SpringEL表示式來指定的。當為true時進行快取處理;為false時不進行快取處理,即每次呼叫該方法都會執行。
  1. @Cacheable(value={"users"}, key="#user.id", condition="#user.id%2==0")  
這個則是當用戶id為偶數的時候才會快取。 [email protected]---------------------------------------- 與@Cacheable不同,它雖然也可以宣告一個方法支援快取,但它執行方法前是不會去檢查快取中是否存在之前執行過的結果,而是每次都執行該方法,並將執行結果放入指定快取中。 [email protected]---------------------------------------- @CacheEvict標註在需要清楚快取元素的方法和類上。@CacheEvict可以指定的屬性有value、key、condition、allEntries和beforeInvocation。value表示清除快取作用在哪個Cache上;key是表示需要清除的是哪個key。 --------------allEntries是表示是否需要清除快取中所有的元素。 --------------beforeInvocation 清除操作預設是在方法成功執行之後觸發的。 使用beforeInvocation可以改變觸發清除操作的時間,當我們設定為true時,Spring會在呼叫該方法之前進行快取的清除。 [email protected]----------------------------------------- @Caching註解可以讓我們在一個方法或者類上同時指定多個Spring Cache相關注解,其中擁有屬性:cacheable、put、evict。 [java]  view plain  copy   print ?
  1. @Caching(cacheable=@Cacheable("users"),evict={@CacheEvict("cache2"),@CacheEvict(value="cache3",allEntries=true)})<span style="font-family: Arial, Helvetica, sans-serif;">    </span>  

-------------------------------------------------------自定義註解----------------------------------------- [java]  view plain  copy   print ?
  1. @Target({ElementType.TYPE, ElementType.METHOD})  
  2. @Retention(RetentionPolicy.RUNTIME)  
  3. @Cacheable(value="users")  
  4. public @interface MyCacheable {  
  5.    
  6. }  
我們在需要快取的方法上面使用@MyCacheable可以達到同樣的快取效果。

---------------------------------------------------------------------------------------------------------------------------------------------- --------------------------配置Spring對Cache的支援 宣告對Cache的支援 1.基於註解 配置Spring對註解Cache的支援,我們需要在Spring配置檔案中新增Cache名稱空間,然後通過<cache:anotation-driven/> 就可以啟動Spring對註解Cache的支援。 其中<cache:anotation-driven/>有一個mode屬性,可以選擇值proxy和aspectj。預設使用proxy。當mode為proxy時,只有快取方法在外部被呼叫的時候才會生效。這也就意味著如果一個快取方法在一個物件的內部被呼叫SpringCache是不會發生作用的。而mode為aspectj時,就不會有這種問題了。另外使用proxy的時候,只有public方法上的@Cacheable才會發生作用。如果想非public上的方法也可以使用那麼就把mode改成aspectj。 注意:當我們mode使用aspectj和proxy-target-class為true時,定義在介面上的Cache註解是無法被識別的。<cache:cache-driven/>只會去尋找定義在同一個ApplicationContext下的@Cacheable等快取註解。
2.基於XML配置 Spring還支援使用XML檔案來配置,方式和配置事務管理類似。 [java]  view plain  copy   print ?
  1. <cache:advice id="cacheAdvice" cache-manager="cacheManager">  
  2.       <cache:caching cache="users">  
  3.          <cache:cacheable method="findById" key="#p0"/>  
  4.          <cache:cacheable method="find" key="#user.id"/>  
  5.          <cache:cache-evict method="deleteAll" all-entries="true"/>  
  6.       </cache:caching>  
  7.    </cache:advice>  
cache-manager預設是cacheManager。其中指定了將findById和find方法快取到users中。也可以使用萬用字元“*” 然後在配置aop:config指定定義好的advice作用到那些地方(pointcut) [java]  view plain  copy   print ?
  1. <aop:config proxy-target-class="false">  
  2.       <aop:advisor advice-ref="cacheAdvice" pointcut="execution(* com.xxx.UserService.*(..))"/>  
  3.    </aop:config>  

3.配置CacheManager CacheManager是Spring定義的一個用來管理Cache的介面。Spring自身提供了兩種,一種是基於JAVA API的ConcurrentMap,另一種是基於第三方Cache實現--Ehcache。 ---------------------基於ConcurrentMap的配置 [java]  view plain  copy   print ?
  1. <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">  
  2.       <property name="caches">  
  3.          <set>  
  4.             <bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean" p:name="xxx"/>  
  5.          </set>  
  6.       </property>  
  7.    </bean>  
p:name則是我們在註解時候使用的value(也就是使用的哪個cache)。 ---------------------基於Ehcache的配置 [java]  view plain  copy   print ?
  1. <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager" p:cache-manager-ref="ehcacheManager"/>  
  2.    <bean id="ehcacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:config-location="ehcache-spring.xml"/>  
它是通過指定的ehcache配置檔案來生成的一個Ehcache的CacheManager。若未指定則預設規則取classpath路徑下的ehcache檔案,若還是不存在則取Ehcache對應包的ehcache-failsafe.xml檔案作為配置檔案。

---------------------------------------------------------鍵的生成策略----------------------------------------------------------- 鍵的生成策略有兩種,一種是預設策略,一種是自定義策略。 ----------------------------預設策略: 預設的key是通過KeyGenerator生成的,其預設策略如下: 1.如果方法沒有引數,則使用0作為key; 2.如果只有一個引數的話則使用該引數作為key; 3.如果引數多於一個則使用所有引數的hashcode作為key;
----------------------------自定義策略: 自定義策略是指我們通過Spring的EL表示式來指定我們的key。這裡的EL表示式可以使用引數以及它們對應的屬性。使用方法引數時我們可以直接使用“#引數名”或者“#p引數index”。