Spring Cache 配置及一些問題的解決


配置

1. applicationContext.xml

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:cache="http://www.springframework.org/schema/cache"
   xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
  
    <cache:annotation-driven />
  <!-- 定義緩存管理 -->
    <bean id="cacheManager" class="org.springframework.cache.support.SimpleCacheManager">
        <property name="caches">
            <set>
                <bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean"
                      p:name="default"/>
                <bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean"
                      p:name="activityCache"/>
                <bean class="org.springframework.cache.concurrent.ConcurrentMapCacheFactoryBean"
                      p:name="awardsCache"/>
            </set>
        </property>
    </bean>

Spring內部默認使用 ConcurrentHashMap 來存儲, 配置中的 activityCache awardsCache 就是一個一個的 ConcurrentHashMap 對象的名字. 另外 spring還支持使用 EHCache 來存儲緩存.

 

2. 在service的實現類上加上 @Cacheable

//@Service
//public class LotteryActivityServiceImpl implements LotteryActivityService

@Cacheable(value = "activityCache", key = "#shortName")
public LotteryActivity findByShortName(String shortName) {
    log.info("query activity : {} from database.", shortName);
    return activityRepository.findByShortName(shortName);
}

 @Cacheable參數

value   緩存的名稱,在 spring 配置文件中定義,必須指定至少一個 例如:@Cacheable(value=”mycache”) 或者 
@Cacheable(value={”cache1”,”cache2”}
key   緩存的 key,可以為空,如果指定要按照 SpEL 表達式編寫,如果不指定,則缺省按照方法的所有參數進行組合 例如:
@Cacheable(value=”testcache”,key=”#userName”)
condition 緩存的條件,可以為空,使用 SpEL 編寫,返回 true 或者 false,只有為 true 才進行緩存 例如:
@Cacheable(value=”testcache”,condition=”#userName.length()>2”)

在需要清除緩存的方法上加上@CacheEvict 

@CacheEvict(value="activityCache", allEntries = true, beforeInvocation = true)
public void cleanActivityCache(String shortName) {
    log.info("cleaned cache activity : {}", shortName);
}

@CacheEvict 參數

value 緩存的名稱,在 spring 配置文件中定義,必須指定至少一個 例如:
@CachEvict(value=”mycache”) 或者 
@CachEvict(value={”cache1”,”cache2”}
key 緩存的 key,可以為空,如果指定要按照 SpEL 表達式編寫,如果不指定,則缺省按照方法的所有參數進行組合 例如:
@CachEvict(value=”testcache”,key=”#userName”
condition 緩存的條件,可以為空,使用 SpEL 編寫,返回 true 或者 false,只有為 true 才清空緩存 例如:
@CachEvict(value=”testcache”,
condition=”#userName.length()>2”)
allEntries 是否清空所有緩存內容,缺省為 false,如果指定為 true,則方法調用后將立即清空所有緩存 例如:
@CachEvict(value=”testcache”,allEntries=true)
beforeInvocation 是否在方法執行前就清空,缺省為 false,如果指定為 true,則在方法還沒有執行的時候就清空緩存,缺省情況下,如果方法執行拋出異常,則不會清空緩存  例如:
@CachEvict(value=”testcache”,beforeInvocation=true)

當需要保證方法被調用,又希望結果被緩存, 可以使用@CachePut 

@CachePut(value="accountCache",key="#account.getName()")// 更新 accountCache 緩存
 public Account updateAccount(Account account) { 
   return updateDB(account); 
 } 

@CachePut 參數

value 緩存的名稱,在 spring 配置文件中定義,必須指定至少一個  例如:
@Cacheable(value=”mycache”) 或者 
@Cacheable(value={”cache1”,”cache2”}
key 緩存的 key,可以為空,如果指定要按照 SpEL 表達式編寫,如果不指定,則缺省按照方法的所有參數進行組合  例如:
@Cacheable(value=”testcache”,key=”#userName”)
condition 緩存的條件,可以為空,使用 SpEL 編寫,返回 true 或者 false,只有為 true 才進行緩存  例如:
@Cacheable(value=”testcache”,condition=”#userName.length()>2”)

 

 注解最好加在實現類而不是接口的方法上

Spring recommends that you only annotate concrete classes (and methods of concrete classes) with the @Cache* annotation, as opposed to annotating interfaces. You certainly can place the @Cache* annotation on an interface (or an interface method), but this works only as you would expect it to if you are using interface-based proxies. The fact that Java annotations are not inherited from interfaces means that if you are using class-based proxies (proxy-target-class="true") or the weaving-based aspect (mode="aspectj"), then the caching settings are not recognized by the proxying and weaving infrastructure, and the object will not be wrapped in a caching proxy, which would be decidedly bad.

帶有@Cache* 注解的方法不能被定義在調用該方法的類里, 比如 UserController要調用 findUserByName(String name), 且該方法有 @Cacheabele注解, 那么該方法就不能被定義在 UserController中

In proxy mode (which is the default), only external method calls coming in through the proxy are intercepted. This means that self-invocation, in effect, a method within the target object calling another method of the target object, will not lead to an actual caching at runtime even if the invoked method is marked with @Cacheable - considering using the aspectj mode in this case.

@Cache*注解要加在 public 方法上

When using proxies, you should apply the @Cache* annotations only to methods with public visibility. If you do annotate protected, private or package-visible methods with these annotations, no error is raised, but the annotated method does not exhibit the configured caching settings. Consider the use of AspectJ (see below) if you need to annotate non-public methods as it changes the bytecode itself.

 

 


免責聲明!

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



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