Ehcache简介

Ehcache是一个纯Java的进程内缓存框架,是Hibernate中默认的CacheProvider,主要面向通用缓存,Java EE和轻量级容器。主要特性有:

  1. 简单快速
  2. 多种缓存策略,支持LRU、LFU和FIFO。
  3. 支持内存和硬盘作为缓存存储
  4. 缓存数据会在虚拟机重启的过程中写入磁盘
  5. 具有缓存和缓存管理器的侦听接口
  6. 可以通过RMI、可插入API等方式进行分布式缓存
  7. 可与spring、Hibernate、shiro等框架组件进行整合

项目中Ehcache的配置

Jeesite中Ehcache的配置文件主要在资源目录下的cache文件夹中,默认使用的是ehcache-local.xmlehcahce-hibernate-xml,前者是ehcache的配置文件,后者是针对hibernate的配置文件。下面先看一下ehcache-local.xml的内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 
 
     overflowToDisk="true" maxEntriesLocalDisk="100000" />
 
 
     
        eternal="true" timeToLiveSeconds="0" timeToIdleSeconds="0"
        diskPersistent="true" diskExpiryThreadIntervalSeconds="600"/>
 
        maxElementsInMemory="100" eternal="true" overflowToDisk="true"/>
 
     timeToIdleSeconds="120" timeToLiveSeconds="120" memoryStoreEvictionPolicy="LFU"/>
     

其中,syscache和cmscache分别是针对系统管理模块和内容管理模块的缓存。SimplePageCachingFilter是页面缓存。各缓存项的含义如下:

  • diskStore path: 缓存保存到磁盘的位置
  • maxElementsInMemory:缓存中允许创建的最大对象数
  • eternal:缓存中对象是否为永久的,如果是,超时设置将被忽略,对象从不过期。
  • timeToIdleSeconds:缓存数据的钝化时间,也就是在一个元素消亡之前,两次访问时间的最大时间间隔值,这只能在元素不是永久驻留时有效。
  • timeToLiveSeconds:缓存数据的生存时间,也就是一个元素从构建到消亡的最大时间间隔值,这只能在元素不是永久驻留时有效。
  • overflowToDisk:内存不足时,是否启用磁盘缓存。

ehcahce-hibernate-xml则是针对sys模块中的实体类通过hibernate来缓存,包括User、Role、Menu、Office、Area、Dict以及userList、MenuList、roleList等实体类。下面列举几个配置,其他的以此类推:

1
2
3

对于页面缓存来说,还要在Servlet容器的web.xml这个配置文件中配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

这里只针对站点首页和html静态页面做了缓存,对应的缓存类是common.filter包下的PageCacheingFilter类。下面就看一下项目中的缓存工具类

项目中的ehcache缓存代码。

首先要针对页面缓存作一下说明,页面缓存主要用Filter过滤器对请求的url进行过滤,如果该url在缓存中出现。那么页面数据就从缓存对象中获取,并以gzip压缩后返回。其速度是没有压缩缓存时速度的3-5倍,效率相当之高!其中页面缓存的过滤器有CachingFilter,一般要扩展filter或是自定义Filter都继承该CachingFilter。CachingFilter功能可以对HTTP响应的内容进行缓存。这种方式缓存数据的粒度比较粗,例如缓存整张页面。EHCache使用SimplePageCachingFilter类实现Filter缓存。现在看一下Jeesite中的Filter:

1
2
3
4
5
6
7
public class PageCachingFilter extends SimplePageCachingFilter {
 
     @Override
     protected CacheManager getCacheManager() {
         return CacheUtils.getCacheManager();
     }  
}

这里的页面缓存过滤器继承了ehcache提供的SimplePageCachingFilter,通过自己写的缓存工具类CacheUtils来获得缓存管理器CacheManager,下面先介绍Ehcache的基本用法,然后对应分析一下CacheUtils类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//获取缓存管理器
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的基本缓存操作做了封装:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
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;
}  
}