基於註解的配置實現spring Cache本地緩存 操作
spring
Guava
cache
- Guava工程包含了若干被Google的 Java項目廣泛依賴 的核心庫
通常來說,Guava Cache適用於:
1.你願意消耗一些內存空間來提升速度。
2.你預料到某些鍵會被查詢一次以上。
3.緩存中存放的數據總量不會超出內存容量。
注意!!! (Guava Cache是單個應用運行時的本地緩存。它不把數據存放到文件或外部服務器。如果這不符合你的需求,請嘗試Memcached, redis緩存架構!!! 個人更推薦redis)- 具體Guava cache說明 可參閱這裏
接下來就該說說spring中Guava的基於註解的實現的配置
當然 ,這裏只說基於註解的配置和使用 我不會去說註解的原理 這不是本文要說的 .
1.首先 新建一個spring-cache.xml配置文件 並將文件配置於web.xml中
2. spring-cahe文件配置如下:
<!-- 聲明緩存註解的開啓 -->
<cache:annotation-driven cache-manager="cacheManager" proxy-target-class="true"/>
<!-- 聲明使用spring管理緩存組 -->
<bean id="cacheManager" class="org.springframework.cache.support.CompositeCacheManager">
<property name="cacheManagers">
<list>
<ref bean="guavaCacheManager"/>
</list>
</property>
<property name="fallbackToNoOpCache" value="true"/>
</bean>
<!-- 緩存的創建的具體實現類注入 class爲自定義的類 -->
<bean id="guavaCacheManager" class="cn.springmvc.cache.GuavaCacheManagerConfig">
<!-- 此處可以配置一組緩存池對應不同的業務類型 這裏我先實現了一個交"likr"的默認緩存並構建 -->
<property name="configMap">
<map key-type="java.lang.String" value-type="com.google.common.cache.CacheBuilder">
<entry key="likr" value-ref="defaultCacheBuilder"/>
</map>
</property>
</bean>
<!-- 此處直接構建"likr"默認緩存 -->
<bean id="defaultCacheBuilder"
class="com.google.common.cache.CacheBuilder"
factory-method="from">
<!-- 緩存池大小 時間(定時回收 緩存項在給定時間內沒有被'寫'訪問 回收 還有refreshAfterWrite expireAfterAccess可供使用) 當然還有一些其他可選組件(weakKeys,removalListener and so on!) -->
<constructor-arg value="maximumSize=10000, expireAfterWrite=1h"/>
</bean>
3.GuavaCacheManagerConfig的具體實現
public class GuavaCacheManagerConfig extends AbstractTransactionSupportingCacheManager {
private final ConcurrentMap<String, Cache> cacheMap = Maps.newConcurrentMap();
private Map<String, CacheBuilder> builderMap = Maps.newHashMap();
@Override
protected Collection<? extends Cache> loadCaches() {
return cacheMap.values();
}
//獲取緩存單例
@Override
public Cache getCache(String name) {
Cache cache = this.cacheMap.get(name);
if (null == cache) {
synchronized (this.cacheMap) {
cache = this.cacheMap.get(name);
if (null == cache && this.builderMap.containsKey(name)) {
CacheBuilder builder = this.builderMap.get(name);
cache = createGuavaCache(name, builder);
this.cacheMap.put(name, cache);
}
}
}
return cache;
}
private Cache createGuavaCache(String name, CacheBuilder builder) {
com.google.common.cache.Cache<Object, Object> cache;
if(builder == null){
cache = CacheBuilder.newBuilder().build();
}else{
cache = builder.build();
}
return new GuavaCache(name, cache, isAllowNullValues());
}
private boolean isAllowNullValues() {
return true;
}
//配置中多組緩存池注入
public void setConfigMap(Map<String, CacheBuilder> configMap) {
this.builderMap = configMap;
}
}
4.代碼中使用:
//spring EL
//LikrUserQuestionnaire 普通的DTO
//@Cacheable(value = "likr", key = "'selectByRecordOne:userId:' + #record.user_id")
//value 爲配置文件中的緩存池名稱 key 爲鍵名
@Override
@Cacheable(value = "likr", key = "'selectByRecordOne:userId:' + #record.user_id")
public LikrUserQuestionnaire selectByRecordOne(LikrUserQuestionnaire record) {
return likrUserQuestionnaireMapper.selectByRecordOne(record);
}