Spring3.1新增了一種緩存機制,這種緩存機制與Spring容器無縫結合在一起,可以對容器中的任意bean或bean的方法增加緩存。Spring的緩存級別更高,可以在控制器組件或業務邏輯組件級別進行緩存,這樣應用完全無需重複調用底層的DAO。
啓動Spring緩存
xml中有一個cache命名空間專門用來配置緩存。啓動緩存需要在xml中添加如下一行:
<cache:annotation-driven chache-manager="緩存管理器ID"/>
該元素指定Spring根據註解來啓動bean級別或方法級別的緩存。此外還需要準對不同的緩存實現配置對應的緩存管理器。
EhCache緩存實現的配置
我們需要將Hibernate\lib\optiona\ehcache下的ehcache-core與slf4j-api兩個jar包添加到項目中。前面是緩存核心包,後面是緩存工具的日誌工具。爲了使用ChCache,我們需要在應用的類加載路徑下添加一個ehcache.xml文件:
<?xml version="1.0" encoding="gbk"?> <ehcache> <diskStore path="java.io.tmpdir"/> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" maxElementsOnDisk="10000000" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU"/> <cache name="users" maxElementsInMemory="10000" eternal="false" overflowToDisk="true" timeToIdleSeconds="300" timeToLiveSeconds="600"/> </ehcache>
上面的文件配置了兩個緩存區,一個是默認的,一個是users。由於這裏使用EhCacheCacheManager作爲緩存管理器,因此我們需要將這個對象配置在Spring容器中。但是EhCaheCacheManager底層需要一個net.sf.ehcache.CacheManager作爲實際的緩存管理器。因此Spring提供了EhCacheManagerFactory
Bean這個工廠Bean,它實現了FactoryBean<CacheManager>接口。當把EhcacheManagerFactoryBean部署在容器中,實際上取用的是它的產品,也就是CacheManager對象。爲了在容器中配置基於EhCache的緩存管理器,只要添加如下兩段代碼即可:
<bean id="ehCacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:configLocation="classpath:ehcache.xml" p:shared="false"/> <bean id="cacheManager" class="prg.springframework.cache.ehcache.EhCacheCacheManager" p:cacheManager=ref="ehCacheManager"/>
首先我們配置了一個叫ehCacheManager的工廠類,它能夠返回CacheManger對象。第二個纔是爲Spring緩存配置的基於EhCache的緩存管理器,它依賴於CacheManager,因此給它注入一個實例變量,也就是第一個工廠bean的索引。上述配置完成,我們就可以使用註解來驅動Spring將緩存數據存入指定緩存區了。
使用@Cacheable執行緩存
可以用@Cacheable來修飾類或者方法,以通知Spring框架在什麼級別上使用緩存。如果是類級別,程序調用實例的任何方法都需要緩存。
類級別的緩存
如果類標註了緩存,那麼對於其中任意方法,只要傳入的參數相同,就回去調用緩存。通過調用緩存得到的兩個實例,是相等的,同一個實例。
@Cacheable(value="users") public class UserServiceimpl implements UserService{ }
如果再增加一個key=”#name"屬性,那麼只要參數的name一樣,就直接調用緩存,雖然其他參數並不一樣,但是不管了!!!!!!!仍然是同一個對象實例。
condition屬性可以指定只要condition表達式爲true纔會執行緩存,比如condition="#age<100",這樣其他參數就會忽略了,只要age這一個小於100,那麼就從緩存中調取,不再執行方法了。而unless則與此正好想反,只要unless後邊的表達式爲true,就不執行緩存。
方法級別的緩存
對方法進行標註,只要傳入相同參數就從緩存掉。也支持上述其它屬性
使用@CacheEvict清除緩存
被@CacheEvict標註的方法可以用來清除緩存。value屬性用於指定清除哪個緩存區屬性,allEntries指定是否清除整個緩存區。beforeInvocation指定是否在方法前清除緩存。默認的是在方法後的。condition指定一個SpEL表達式,只有當true才清除。key可以通過SpEL表達式顯式地指定緩存的key。