Ehcache 2.x 快速使用 & Spring 集成

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
 
 version="1.0" encoding="UTF-8"?>
<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();

配置文件详解

  • :指定磁盘缓存位置,由 path 属性进行指定;
  • :默认缓存配置;
  • ache>:缓存配置,包含以下常用属性:
    • 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
 
 version="1.0" encoding="UTF-8"?>
<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>
    
    <cache name="users"
           maxElementsInMemory="2000"
           maxElementsOnDisk="100000"
           eternal="false"
           timeToIdleSeconds="300"
           timeToLiveSeconds="1200"
           memoryStoreEvictionPolicy="LRU"
           overflowToDisk="true" />
ehcache>

创建 Spring 上下文配置文件: applicationContetx.xml
 
 version="1.0" encoding="UTF-8"?>
<beans ....>
    
    <context:component-scan base-package="site.assad.service" />
    
    
    
    <cache:annotation-driven/>
    
    <bean id="cacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager"
          p:cacheManager-ref="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;
@Service
public class UserService {
    private final static Logger log = LogManager.getLogger();
    //获取元素
    @Cacheable(cacheNames = "users", key="#userId")
    public User getUser(@CacheKey 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 从缓存中删除
    @CacheEvict(cacheNames = "users", key="#userId")
    public void removeUserFromCache(@CacheKey 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();
    @Before
    public void initContext(){
        userService = new ClassPathXmlApplicationContext("classpath:applicationContext.xml").getBean("userService",UserService.class);
    }
    //测试缓存队列
    @Test
    public void testGetUser(){
        for(int i=1;i<5;i++){
            log.debug("query get User(userId=1)"+i+" ...");
            log.debug(userService.getUser(1));
        }
    }
    //测试删除缓存队列
    @Test
    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



你可能感兴趣的:(Java,Spring4)