Spring Cache使用詳解


Spring Cache

Spring Cache使用方法與Spring對事務管理的配置相似。Spring Cache的核心就是對某個方法進行緩存,其實質就是緩存該方法的返回結果,並把方法參數和結果用鍵值對的方式存放到緩存中,當再次調用該方法使用相應的參數時,就會直接從緩存里面取出指定的結果進行返回。所以在使用Cache的時候我們要保證我們緩存的方法對於相同的參數要有相同的返回結果。
-----------Spring對Cache的支持有兩種方法:
1.基於注解的配置
2.基礎XML配置

-----------------------------------------------------通過注解去使用到Cache------------------------------------------
@Cacheable-------使用這個注解的方法在執行后會緩存其返回結果。
@CacheEvict--------使用這個注解的方法在其執行前或執行后移除Spring Cache中的某些元素。

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

----------------------value:指定Cache的名稱
value值是必須指定的,其表示該方法緩存的返回結果是被緩存在哪個Cache上的,對應Cache的名稱。其可以是一個Cache也可以使多個Cache(數組);
eg:
[java]  view plain  copy
 print ?
  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表達式可以使用方法參數以及他們對應的屬性。使用方法參數時,我們可以使用“#參數名”。
eg:
[java]  view plain  copy
 print ?
  1. @Cacheable(value="users", key="#id")  
  2. public User find(Integer id) {  
  3.      returnnull;  
  4. }  

[java]  view plain  copy
 print ?
  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時不進行緩存處理,即每次調用該方法都會執行。
eg:
[java]  view plain  copy
 print ?
  1. @Cacheable(value={"users"}, key="#user.id", condition="#user.id%2==0")  
這個則是當用戶id為偶數的時候才會緩存。

-----------------------------------------------------@CachePut------------------------------------------
與@Cacheable不同,它雖然也可以聲明一個方法支持緩存,但它執行方法前是不會去檢查緩存中是否存在之前執行過的結果,而是每次都執行該方法,並將執行結果放入指定緩存中。
-----------------------------------------------------@CacheEvict----------------------------------------
@CacheEvict標注在需要清楚緩存元素的方法和類上。@CacheEvict可以指定的屬性有value、key、condition、allEntries和beforeInvocation。value表示清除緩存作用在哪個Cache上;key是表示需要清除的是哪個key。
--------------allEntries是表示是否需要清除緩存中所有的元素。
--------------beforeInvocation
清除操作默認是在方法成功執行之后觸發的。 使用beforeInvocation可以改變觸發清除操作的時間,當我們設置為true時,Spring會在調用該方法之前進行緩存的清除。
------------------------------------------------------@Caching-------------------------------------------
@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”。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM