首先,需要两个jar包,ehcache-core-2.4.3.jar,slf4j-api-1.6.1.jar;
需要把ehcache.xml放在类加载路径,既可放在src包下(推荐),也可以放在classes文件夹下;
以下是配置文件ehcache.xml例子:
<!-- <ehcache xsi:noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true" monitoring="autodetect" dynamicConfig="true"> <diskStore path="java.io.tmpdir"/> <transactionManagerLookup class="net.sf.ehcache.transaction.manager.DefaultTransactionManagerLookup" properties="jndiName=java:/TransactionManager" propertySeparator=";"/> <cacheManagerEventListenerFactory class="" properties=""/> <terracottaConfig url="localhost:9510"/> <defaultCache maxEntriesLocalHeap="0" eternal="false" timeToIdleSeconds="1200" timeToLiveSeconds="1200"> <terracotta/> </defaultCache> <cache name="sampleCache1" maxEntriesLocalHeap="10000" maxEntriesLocalDisk="1000" eternal="false" diskSpoolBufferSizeMB="20" timeToIdleSeconds="300" timeToLiveSeconds="600" memoryStoreEvictionPolicy="LFU" transactionalMode="off"><persistence strategy="localTempSwap"/></cache> <cache name="sampleCache2" maxEntriesLocalHeap="1000" eternal="true" memoryStoreEvictionPolicy="FIFO"/> <cache name="sampleCache3" maxEntriesLocalHeap="500" eternal="false" overflowToDisk="true" diskPersistent="true" timeToIdleSeconds="300" timeToLiveSeconds="600" diskExpiryThreadIntervalSeconds="1" memoryStoreEvictionPolicy="LFU"> </cache> <cache name="sampleTerracottaCache" maxBytesLocalHeap="10m" eternal="false" timeToIdleSeconds="3600" timeToLiveSeconds="1800"> <terracotta/> </cache> </ehcache> --> <!-- 设定具体的命名缓存的数据过期策略 cache元素的属性: name:缓存名称 maxElementsInMemory:内存中最大缓存对象数 maxElementsOnDisk:硬盘中最大缓存对象数,若是0表示无穷大 eternal:true表示对象永不过期,此时会忽略timeToIdleSeconds和timeToLiveSeconds属性,默认为false overflowToDisk:true表示当内存缓存的对象数目达到了maxElementsInMemory界限后,会把溢出的对象写到硬盘缓存中。注意:如果缓存的对象要写入到硬盘中的话,则该对象必须实现了Serializable接口才行。 diskSpoolBufferSizeMB:磁盘缓存区大小,默认为30MB。每个Cache都应该有自己的一个缓存区。 diskPersistent:是否缓存虚拟机重启期数据 diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认为120秒 timeToIdleSeconds: 设定允许对象处于空闲状态的最长时间,以秒为单位。当对象自从最近一次被访问后,如果处于空闲状态的时间超过了timeToIdleSeconds属性值,这个对象就会过期,EHCache将把它从缓存中清空。只有当eternal属性为false,该属性才有效。如果该属性值为0,则表示对象可以无限期地处于空闲状态 timeToLiveSeconds:设定对象允许存在于缓存中的最长时间,以秒为单位。当对象自从被存放到缓存中后,如果处于缓存中的时间超过了 timeToLiveSeconds属性值,这个对象就会过期,EHCache将把它从缓存中清除。只有当eternal属性为false,该属性才有效。如果该属性值为0,则表示对象可以无限期地存在于缓存中。timeToLiveSeconds必须大于timeToIdleSeconds属性,才有意义 memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。可选策略有:LRU(最近最少使用,默认策略)、FIFO(先进先出)、LFU(最少访问次数)。 --> <ehcache> <!-- 指定一个文件目录,当EHCache把数据写到硬盘上时,将把数据写到这个文件目录下 --> <diskStore path="java.io.tmpdir"/> <!-- 设定缓存的默认数据过期策略 --> <!-- <defaultCache maxElementsInMemory="10000" eternal="false" overflowToDisk="true" timeToIdleSeconds="0" timeToLiveSeconds="0" diskPersistent="false" diskExpiryThreadIntervalSeconds="120"/> --> <!-- 设置缓存数据的策略 --> <cache name="users" maxElementsInMemory="10" eternal="false" overflowToDisk="true" timeToIdleSeconds="0" timeToLiveSeconds="0" diskPersistent="false" diskSpoolBufferSizeMB="100" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LFU"/> </ehcache>
以下是spring-servlet.xml配置文件需要增加的配置:
<bean id="ehcacheManager" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"> <property name="configLocation" value="classpath:ehcache.xml"/> </bean> <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager"> <property name="cacheManager" ref="ehcacheManager"/> <property name="transactionAware" value="true"/> </bean> <cache:annotation-driven cache-manager="cacheManager" proxy-target-class="true"/>
以下是Java代码例子:
@Service("indexService")
@Cacheable(value = "users")
public class IndexServiceImpl implements IndexService{
@Resource(name = "userDao")
private UserDao userDao;
@Override
@Transactional(propagation=Propagation.REQUIRED, isolation=Isolation.DEFAULT, timeout=5)
public IndexModel checkLogin(IndexModel indexModel) {
User user = userDao.findByUsername(indexModel.getUsername());
if(user != null && user.getPassword().equals(indexModel.getPassword())) {
System.out.println(indexModel.getUsername());
return indexModel;
} else {
// ModelAndView mv = new ModelAndView();
// mv.addObject("loginResult", "登陆失败");
// mv.setViewName("loginResult");
System.out.println(indexModel.getUsername());
return indexModel;
}
}
}
@Cacheable修饰的是类,表明这是类级别的缓存,即全部方法都会根据册罗进行缓存,存放缓存数据的路径是Java的临时路径,对应的缓存数据的策略是名为"users"的缓存策略,内存存够10条element后,数据将会存在名为"users.data"的文件夹;
通常应该使用方法级别的缓存,因为如果用上类级别的缓存,会出现这种情况:传入a参数,调用a方法,spring缓存了a方法对应于a参数的返回值,传入a参数,调用b方法,b方法并不会被调用,而是返回缓存里的a方法对应于a参数的返回值,很多情况下,这不是我们想要的,且这样会比较不明确,比较容易出现错误;
浙公网安备 33010602011771号