Ehcache简介
Ehcache是一个纯Java的进程内缓存框架,是Hibernate中默认的CacheProvider,主要面向通用缓存,Java EE和轻量级容器。主要特性有:
- 简单快速
- 多种缓存策略,支持LRU、LFU和FIFO。
- 支持内存和硬盘作为缓存存储
- 缓存数据会在虚拟机重启的过程中写入磁盘
- 具有缓存和缓存管理器的侦听接口
- 可以通过RMI、可插入API等方式进行分布式缓存
- 可与spring、Hibernate、shiro等框架组件进行整合
项目中Ehcache的配置
Jeesite中Ehcache的配置文件主要在资源目录下的cache文件夹中,默认使用的是ehcache-local.xml
和ehcahce-hibernate-xml
,前者是ehcache的配置文件,后者是针对hibernate的配置文件。下面先看一下ehcache-local.xml
的内容:
<ehcache updateCheck="false" name="defaultCache">
<diskStore path="java.io.tmpdir/jeesite/ehcache/default" />
<!-- DefaultCache setting. -->
<defaultCache maxEntriesLocalHeap="100" eternal="false" timeToIdleSeconds="300" timeToLiveSeconds="600"
overflowToDisk="true" maxEntriesLocalDisk="100000" />
<cache name="sysCache" maxElementsInMemory="100" eternal="true" overflowToDisk="true"/>
<cache name="cmsCache" maxElementsInMemory="100" eternal="true" overflowToDisk="true"/>
<cache name="shiro-activeSessionCache" maxElementsInMemory="100" overflowToDisk="true"
eternal="true" timeToLiveSeconds="0" timeToIdleSeconds="0"
diskPersistent="true" diskExpiryThreadIntervalSeconds="600"/>
<cache name="org.apache.shiro.realm.text.PropertiesRealm-0-accounts"
maxElementsInMemory="100" eternal="true" overflowToDisk="true"/>
<cache name="SimplePageCachingFilter" maxElementsInMemory="100" eternal="false" overflowToDisk="true"
timeToIdleSeconds="120" timeToLiveSeconds="120" memoryStoreEvictionPolicy="LFU"/>
</ehcache>
其中,syscache和cmscache分别是针对系统管理模块和内容管理模块的缓存。SimplePageCachingFilter是页面缓存。各缓存项的含义如下:
- diskStore path: 缓存保存到磁盘的位置
- maxElementsInMemory:缓存中允许创建的最大对象数
- eternal:缓存中对象是否为永久的,如果是,超时设置将被忽略,对象从不过期。
- timeToIdleSeconds:缓存数据的钝化时间,也就是在一个元素消亡之前,两次访问时间的最大时间间隔值,这只能在元素不是永久驻留时有效。
- timeToLiveSeconds:缓存数据的生存时间,也就是一个元素从构建到消亡的最大时间间隔值,这只能在元素不是永久驻留时有效。
- overflowToDisk:内存不足时,是否启用磁盘缓存。
而ehcahce-hibernate-xml
则是针对sys模块中的实体类通过hibernate来缓存,包括User、Role、Menu、Office、Area、Dict以及userList、MenuList、roleList等实体类。下面列举几个配置,其他的以此类推:
<cache name="com.thinkgem.jeesite.modules.sys.entity.Area" maxEntriesLocalHeap="100" eternal="false" overflowToDisk="true" maxEntriesLocalDisk="100000" />
<cache name="com.thinkgem.jeesite.modules.sys.entity.Area.childList" maxEntriesLocalHeap="100" eternal="false" overflowToDisk="true" maxEntriesLocalDisk="100000" />
<cache name="com.thinkgem.jeesite.modules.sys.entity.Area.officeList" maxEntriesLocalHeap="100" eternal="false" overflowToDisk="true" maxEntriesLocalDisk="100000" />
对于页面缓存来说,还要在Servlet容器的web.xml
这个配置文件中配置:
<!-- Ehcache 页面缓存,仅缓存首页和html为后缀的页面 (需要时取消注释)
<filter>
<filter-name>PageCacheFilter</filter-name>
<filter-class>com.thinkgem.jeesite.common.filter.PageCachingFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>PageCacheFilter</filter-name>
<url-pattern>/</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>PageCacheFilter</filter-name>
<url-pattern>*.html</url-pattern>
</filter-mapping>-->
这里只针对站点首页和html静态页面做了缓存,对应的缓存类是common.filter包下的PageCacheingFilter类。下面就看一下项目中的缓存工具类
项目中的ehcache缓存代码。
首先要针对页面缓存作一下说明,页面缓存主要用Filter过滤器对请求的url进行过滤,如果该url在缓存中出现。那么页面数据就从缓存对象中获取,并以gzip压缩后返回。其速度是没有压缩缓存时速度的3-5倍,效率相当之高!其中页面缓存的过滤器有CachingFilter,一般要扩展filter或是自定义Filter都继承该CachingFilter。CachingFilter功能可以对HTTP响应的内容进行缓存。这种方式缓存数据的粒度比较粗,例如缓存整张页面。EHCache使用SimplePageCachingFilter类实现Filter缓存。现在看一下Jeesite中的Filter:
public class PageCachingFilter extends SimplePageCachingFilter {
@Override
protected CacheManager getCacheManager() {
return CacheUtils.getCacheManager();
}
}
这里的页面缓存过滤器继承了ehcache提供的SimplePageCachingFilter,通过自己写的缓存工具类CacheUtils来获得缓存管理器CacheManager,下面先介绍Ehcache的基本用法,然后对应分析一下CacheUtils类:
//获取缓存管理器
CacheManager cacheManager = CacheManager.create();
cacheManager = CacheManager.getInstance();
cacheManager = CacheManager.newInstance("/config/ehcache.xml");
//通过缓存管理器获取ehcache配置文件中的一个cache
Cache sample = cacheManager.getCache("sample");
//添加数据到缓存中
Element element = new Element("key", "val");
sample.put(element);
//获取缓存中的对象,注意添加到cache中对象要序列化 实现Serializable接口
Element result = sample.get("key");
// 删除缓存
sample.remove("key");
sample.removeAll();
CahceUtils类就是对这些Ehcache的基本缓存操作做了封装:
public class CacheUtils {
//通过Spring来获取缓存管理器
private static CacheManager cacheManager = ((CacheManager)SpringContextHolder.getBean("cacheManager"));
//对应ehcache-local.xml配置的系统模块缓存
private static final String SYS_CACHE = "sysCache";
//以下是针对系统模块缓存的操作
public static Object get(String key) {
return get(SYS_CACHE, key);
}
public static void put(String key, Object value) {
put(SYS_CACHE, key, value);
}
public static void remove(String key) {
remove(SYS_CACHE, key);
}
//封装Ehcache的get put remove操作
public static Object get(String cacheName, String key) {
Element element = getCache(cacheName).get(key);
return element==null?null:element.getObjectValue();
}
public static void put(String cacheName, String key, Object value) {
Element element = new Element(key, value);
getCache(cacheName).put(element);
}
public static void remove(String cacheName, String key) {
getCache(cacheName).remove(key);
}
/**
* 获得一个Cache,没有则创建一个。
* @param cacheName
* @return
*/
private static Cache getCache(String cacheName){
Cache cache = cacheManager.getCache(cacheName);
if (cache == null){
cacheManager.addCache(cacheName);
cache = cacheManager.getCache(cacheName);
cache.getCacheConfiguration().setEternal(true);
}
return cache;
}
public static CacheManager getCacheManager() {
return cacheManager;
}
}