Ehcache 2.x 快速使用
简介
Ehcache 是一个开源的高性能缓存,拥有很高的拓展性和伸缩性,广泛使用各种 Java 项目中(如 Hibernate 默认使用 Ehcache作为二级缓存),在目前基于 Java 的缓存方案里,几乎是性能最高的实现;
Ehcache 2.10 技术文档:http://www.ehcache.org/generated/2.10.4/html/ehc-all/
使用 Ehcache 需要导入依赖:
net.sf.ehcache:ehcache
如在 Gradle 中:
dependencies {
compile 'net.sf.ehcache:ehcache:2.10.4'
}
Ehcache 支持以下 3 层储存
- heap:JVM heap 堆缓存,速度最快;
- offheap:JVM 堆外内存缓存,速度低于 heap,但是高于 disk;
- disk:磁盘缓存,速度最慢;
基本使用
以下演示通过 XML 文件方式配置 Ehcache 2.x;
在项目根目录创建XML配置文件:
ehcache.xml
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
<!-- 磁盘缓存位置 -->
<diskStore path="java.io.tmpdir/ehcache"/>
<!-- 配置默认缓存 -->
<defaultCache
maxEntriesLocalHeap="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
maxEntriesLocalDisk="10000000"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
<persistence strategy="localTempSwap"/>
</defaultCache>
<!-- 配置一个缓存 -->
<cache name="myCache"
maxElementsInMemory="1000"
overflowToDisk="false"
memoryStoreEvictionPolicy="LRU"/>
</ehcache>
使用缓存代码:
//创建缓存管理器
CacheManager cacheManager = CacheManager.create("./src/main/resources/ehcache.xml");
//获取缓存对象
Cache cache = cacheManager.getCache("myCache");
//添加缓存条目
Element e1 = new Element(1L,"Hello world!");
Element e2 = new Element(2L,new User("assad","Guangzhou",20));
cache.put(e1);
cache.put(e2);
//获取缓存条目
Element e3 = cache.get(1L);
String str = (String)e3.getObjectValue();
Element e4 = cache.get(2L);
User user = (User)e4.getObjectValue();
//刷新缓存
cache.flush();
//关闭缓存管理器
cacheManager.shutdown();
配置文件详解
- <diskStore>:指定磁盘缓存位置,由 path 属性进行指定;
- <defaultCache>:默认缓存配置;
- <cache>:缓存配置,包含以下常用属性:
-
name:缓存名称;
-
eternal: 设置缓存中元素是否为永久,如果设置为 true,则元素永不过期;
-
timeToIdleSeconds: TTI策略(固定空闲期策略)元素超时时间,只有 enternal = ”false“ 才生效‘;
-
timeToLiveSeconds: TTL策略(固定存货时间策略)元素超时时间,只有 enternal = ”false“ 才生效‘;
- maxElementsInMemory: 内存中允许储存的最大元素个数,0 代表无限;
- memoryStoreEvictionPolicy: 内存释放策略,包括哟 LRU(最近最少使用)、LFU(最常使用)、FIFO(先进先出);
- clearOnFlush: 内存元素数量到达最大时,是否清除;
- overflowToDisk: 内存不足时,是否启动磁盘储存;
- maxEntriesLoaclDisk: 内存中储存元素到达该值时,超出的元素会进入磁盘;
- maxElementsDisk: 磁盘中允许储存的最大元素个数,0 代表无限;
- diskSpoolBufferSizeMB: 设置磁盘储存缓冲区的带下,默认 30MB;
- diskExpiryThreadIntervalSeconds: 磁盘缓存的清理线程运行间隔,默认是120秒;
- diskPersistent: 设置磁盘储存是否持久化,默认false;
-
Spring 4 集成 Ehcache 2.X
以下示例完整代码地址:
https://gitee.com/assad/spring_ehcache_sample
构建依赖脚本
build.gradle
apply plugin: 'java'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
//ehcache 依赖
compile 'net.sf.ehcache:ehcache:2.10.4'
//spring core 依赖
compile "org.springframework:spring-beans:4.3.14.RELEASE"
compile "org.springframework:spring-core:4.3.14.RELEASE"
compile "org.springframework:spring-context-support:4.3.14.RELEASE"
//spring test 依赖
compile "org.springframework:spring-test:4.3.14.RELEASE"
testCompile "junit:junit:4.12"
//log4j 依赖
compile 'org.slf4j:slf4j-nop:1.7.25'
compile "org.apache.logging.log4j:log4j-core:2.9.0"
compile "org.apache.logging.log4j:log4j-api:2.9.0"
}
创建 ehcahe 配置文件:
ehcache.xml
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
<!--磁盘储存配置-->
<diskStore path="java.io.tmpdir/ehcache" />
<!--默认缓存配置-->
<defaultCache>
<persistence strategy="localTempSwap" />
</defaultCache>
<!--配置 users 缓存-->
<cache name="users"
maxElementsInMemory="2000"
maxElementsOnDisk="100000"
eternal="false"
timeToIdleSeconds="300"
timeToLiveSeconds="1200"
memoryStoreEvictionPolicy="LRU"
overflowToDisk="true" />
</ehcache>
创建 Spring 上下文配置文件:
applicationContetx.xml
<beans ....>
<!--扫描bean-->
<context:component-scan base-package="site.assad.service" />
<!--Spring Cache 配置:使用 Ehcache 2.x 作为缓存方案-->
<!--启动基于注解的缓存配置-->
<cache:annotation-driven/>
<!--配置 spring 缓存管理器-->
<bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager"
p:cacheManager-ref="ehcache" />
<!--配置 ehcache 缓存管理器-->
<bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean"
p:configLocation="classpath:ehcache.xml" />
</beans>
编写 Service 层,
site.assad.service.UserService
package site.assad.service;
public class UserService {
private final static Logger log = LogManager.getLogger();
//获取元素
cacheNames = "users", key="#userId") (
public User getUser( int userId) {
log.debug("real query user from DB");
//模拟从数据库中获取 User 对象
User user = new User();
user.setId(userId);
user.setName("assad");
user.setPassword("233333");
user.setIcon("icon-001");
return user;
}
//将 userId 对应的 User 从缓存中删除
cacheNames = "users", key="#userId") (
public void removeUserFromCache( int userId){
log.debug("remove user "+ userId + " from cache");
}
}
测试 service 层,
site.assad.service.UserServiceTest
public class UserServcieTest {
private UserService userService;
private final static Logger log = LogManager.getLogger();
public void initContext(){
userService = new ClassPathXmlApplicationContext("classpath:applicationContext.xml").getBean("userService",UserService.class);
}
//测试缓存队列
public void testGetUser(){
for(int i=1;i<5;i++){
log.debug("query get User(userId=1)"+i+" ...");
log.debug(userService.getUser(1));
}
}
//测试删除缓存队列
public void testRemoveUserFromCache(){
for(int i=1;i<5;i++){
log.debug("query get User(userId=1)"+i+" ...");
log.debug(userService.getUser(1));
}
userService.removeUserFromCache(1);
log.debug("query get User(userId=1)"+6+" ...");
log.debug(userService.getUser(1));
}
}
其中关于 Spring 中用于缓存操作的注解,如 @Cacheable,@CachePut,@CacheEvict 等的用法,参见:
http://blog.csdn.net/al_assad/article/details/79107113
http://blog.csdn.net/al_assad/article/details/79107113