- 首先,需要添加連個jar包:ehcache-core-2.6.11.jar和slf4j-api-1.7.21.jar
- 在類加載路徑下添加一個ehcache.xml配置文件,文件內容如下:
<?xml version="1.0" encoding="utf-8"?> <ehcache> <diskStore path="java.io.tmpdir"/> <!-- 配置默認的緩存區 --> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" maxElementsOnDisk="10000000" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU"/> <!-- 配置名為users的緩存區 --> <cache name="users" maxElementsInMemory="10000" eternal="false" overflowToDisk="true" timeToIdleSeconds="300" timeToLiveSeconds="600" /> <!-- maxElementsInMemory : 設置屬性中最多可以放多少個對象 eternal:設置緩存是否永久有效 timeToIdleSeconds:設置緩存的對象多少秒沒有被使用就會清理掉 timeToLiveSeconds:設置緩存的對象在過期之前可以緩存多少秒 diskPersistent:設置緩存是否被持久化到硬盤中,保存路徑由<diskStore.../>元素指定 --> </ehcache>
3.在spring的配置文件bean.xml中進行配置:
<cache:annotation-driven /> <context:component-scan base-package="com.XXX.XXX"/> <!-- 配置EhCache的CacheManager 通過configLocation指定ehcache.xml文件的位置 --> <bean id="ehCacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" p:configLocation="classpath:ehcache.xml" p:shared="false"/> <!-- 配置基於EhCache的緩存管理器,並將EhCache的CacheManager注入該緩存管理器Bean中 --> <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager" p:cacheManager-ref="ehCacheManager"/>
上面代碼中<cache:annotation-driven />的作用是啟用緩存注解功能,這個是必須的,否則注解不會生效,另外,該注解一定要聲明在spring主配置文件中才會生效
<cache:annotation-driven/>有一個cache-manager屬性用來指定當前所使用的CacheManager對應的bean的名稱,默認是cacheManager,所以當我們的CacheManager的id為cacheManager時我們可以不指定該參數,否則就需要我們指定了。
<cache:annotation-driven/>還可以指定一個mode屬性,可選值有proxy和aspectj。默認是使用proxy。當mode為proxy時,只有緩存方法在外部被調用的時候Spring Cache才會發生作用,這也就意味着如果一個緩存方法在其聲明對象內部被調用時Spring Cache是不會發生作用的。而mode為aspectj時就不會有這種問題。另外使用proxy時,只有public方法上的@Cacheable等標注才會起作用,如果需要非public方法上的方法也可以使用Spring Cache時把mode設置為aspectj。
此外,<cache:annotation-driven/>還可以指定一個proxy-target-class屬性,表示是否要代理class,默認為false。我們前面提到的@Cacheable、@cacheEvict等也可以標注在接口上,這對於基於接口的代理來說是沒有什么問題的,但是需要注意的是當我們設置proxy-target-class為true或者mode為aspectj時,是直接基於class進行操作的,定義在接口上的@Cacheable等Cache注解不會被識別到,那對應的Spring Cache也不會起作用了。
需要注意的是<cache:annotation-driven/>只會去尋找定義在同一個ApplicationContext下的@Cacheable等緩存注解。
4.使用@Cacheable執行緩存
import org.springframework.cache.annotation.CacheEvict; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; @Service("userService") @Cacheable(value="users") public class UserServiceImpl implements UserService{ public User getUsersByNameAndAge(String name,int age){ System.out.println("--正在執行findUsersByNameAndAge()查詢方法--"); return new User(name,age); } public User getAnotherUser(String name,int age){ System.out.println("--正在執行findAnotherUser()查詢方法--"); return new User(name,age); } }
5.測試
import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class SpringTest { public static void main(String[] args) { ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml"); UserService us = ctx.getBean("userService",UserService.class); User u1 = us.getUsersByNameAndAge("孫悟空", 500); User u2 = us.getAnotherUser("孫悟空", 500); System.out.println(u1==u2); }
上面結果輸出true,表示第二次是從緩存中獲取對象