1.ehcache.xml 配置
<?xml version="1.0" encoding="UTF-8"?>
<ehcache
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
updateCheck="false">
<diskStore path="c:\\ehcache"/>
<cache name = "EhcacheDefaultCache"
maxElementsInMemory = "20000"
maxElementsOnDisk = "0"
eternal = "false"
overflowToDisk = "false"
diskPersistent = "false"
timeToIdleSeconds = "1800"
timeToLiveSeconds = "1800"
diskSpoolBufferSizeMB = "200"
diskExpiryThreadIntervalSeconds = "10"
memoryStoreEvictionPolicy = "FIFO"
>
<cacheEventListenerFactory class="com.seryo.cache.MyCacheEventListenerFactory"/>
</cache>
<!--
name: Cache的名称,必须是唯一的(ehcache会把这个cache放到HashMap里)。
maxElementsInMemory: 在内存中缓存的element的最大数目。
maxElementsOnDisk: 在磁盘上缓存的element的最大数目,默认值为0,表示不限制。
eternal: 设定缓存的elements是否永远不过期。如果为true,则缓存的数据始终有效,如果为false那么还要根据timeToIdleSeconds,timeToLiveSeconds判断。
overflowToDisk: 如果内存中数据超过内存限制,是否要缓存到磁盘上。
以下属性是可选的:
timeToIdleSeconds: 对象空闲时间,指对象在多长时间没有被访问就会失效。只对eternal为false的有效。默认值0,表示一直可以访问。
timeToLiveSeconds: 对象存活时间,指对象从创建到失效所需要的时间。只对eternal为false的有效。默认值0,表示一直可以访问。
diskPersistent: 是否在磁盘上持久化。指重启jvm后,数据是否有效。默认为false。
diskExpiryThreadIntervalSeconds: 对象检测线程运行时间间隔。标识对象状态的线程多长时间运行一次。
diskSpoolBufferSizeMB: DiskStore使用的磁盘大小,默认值30MB。每个cache使用各自的DiskStore。
memoryStoreEvictionPolicy: 如果内存中数据超过内存限制,向磁盘缓存时的策略。默认值LRU,可选FIFO、LFU。
缓存的3 种清空策略 :
FIFO ,first in first out (先进先出).
LFU , Less Frequently Used (最少使用).意思是一直以来最少被使用的。缓存的元素有一个hit 属性,hit 值最小的将会被清出缓存。
LRU ,Least Recently Used(最近最少使用). (ehcache 默认值).缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。
-->
</ehcache>
2.基础类配置
package com.seryo.util;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheException;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
/**
* ehcache 工具类
*/
public class EhcacheKit {
private static CacheManager manager = null;
private static String configfile="ehcache.xml";
private static interface Helper {
Map<String,EhcacheKit> INSTANCES = new HashMap<>();
}
private Cache cache;
private Timer timer;
//EHCache初始化
private static void init() {
try {
if(manager == null) {
ClassLoader clas = EhcacheKit.class.getClassLoader();
manager = CacheManager.create(clas.getResourceAsStream(configfile));
}
} catch (CacheException e) {
e.printStackTrace();
}
}
/**
* 将数据存入Cache
* @param cachename Cache名称
* @param key 类似redis的Key
* @param value 类似redis的value,value可以是任何对象、数据类型,比如person,map,list等
*/
public void put(String key, Object value, int seconds){
Element ele = new Element(key, value);
if(seconds != 0) {//失效时的间隔时间 和最后一次操作时间间隔
ele.setTimeToLive(seconds);
ele.setTimeToIdle(seconds);
}
cache.put(ele);
}
/**
* 获取缓存cachename中key对应的value
* @param cachename
* @param key
* @return
*/
public Element get(String key){
try {
Element e = cache.get(key);
if(e == null){
return null;
}
return e;
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (CacheException e) {
e.printStackTrace();
}
return null;
}
/**
* 清除缓存名称为cachename的缓存
* @param cachename
*/
public void clearCache(){
try {
cache.removeAll();
} catch (IllegalStateException e) {
e.printStackTrace();
}
}
/**
* 判断缓存是否存在
* @throws
*/
public boolean exist(String key){
if(get(key) != null){
return true;
}
return false;
}
/**
* 移除缓存cachename中key对应的value
* @param cachename
* @param key
* @return
*/
public boolean remove(String key){
boolean flag = cache.remove(key);
cache.flush();
return flag;
}
/**
* 使缓存在某个时间过期
* @throws
*/
public boolean expire(String key, int timeout){
boolean boo = false;
Element el = get(key);
if(el != null){
Object value = el.getObjectValue();
put(key, value, timeout);
boo = true;
}
return boo;
}
/**
* 使缓存在某个时间过期
* @throws
*/
public boolean expireAt(String key, int timeout){
return expire(key, timeout);
}
public void evictExpiredElements(){
cache.evictExpiredElements();
}
/**
* 获取实例
*
* @category 获取实例
* @return
*/
public static EhcacheKit getInstance(String cachename) {
init();
EhcacheKit instance = Helper.INSTANCES.get(cachename);
if(instance != null) {
return instance;
}
instance = new EhcacheKit();
instance.cache = manager.getCache(cachename);
instance.timer = new Timer();
EhcacheKit _instance = instance;
//默认时不会自动触发监听过期失效 只有访问才能触发 ,这里是为了让程序1分钟监听一次过期失效
instance.timer.schedule(new TimerTask() {//1分钟监听一次过期失效
@Override
public void run() {
_instance.cache.evictExpiredElements();
}
}, 500,1000);
return instance;
}
}
3.调用接口(因为是和redis用相同调用)
package com.seryo.cache;
import java.util.List;
import com.seryo.util.EhcacheKit;
import com.seryo.vo.LogObject;
/**
* EhcacheCache 缓存
* @Package com.seryo.cache
* @ClassName: EhcacheCache
* @author hjj
*/
public class EhcacheCache implements Cache {
private EhcacheKit kit() {
return EhcacheKit.getInstance(this.getClass().getSimpleName());
};
@Override
public <T> T get(String key) {
return (T) kit().get(key);
}
@Override
public <T> void set(String key, T value, long timeout) {
kit().put(key, value, (int)timeout);
}
@Override
public boolean expire(String key, long timeout) {
return kit().expire(key, (int)timeout);
}
@Override
public boolean exist(String key) {
return kit().exist(key);
}
@Override
public <T> void setExpireAt(String key, T value, long expireAt) {
kit().put(key, value, (int)expireAt);
}
@Override
public boolean expireAt(String key, long expireAt) {
return kit().expireAt(key, (int)expireAt);
}
@Override
public boolean del(String key) {
return kit().remove(key);
}
/**
* 清除该缓存配置方案的所有内容
* @throws
*/
public void delAll() {
kit().clearCache();
}
}
Cache
package com.seryo.cache;
import java.util.List;
import com.seryo.vo.LogObject;
/**
* 缓存接口
*
* @category 缓存接口
* @version 1.0
*/
public interface Cache {
public static final String CACHE_FLAG = "Cache";
/**
* 设置缓存
*
* @category 设置缓存
* @param key
* @param value
* @param timeout
* ms
*/
public <T> void set(String key, T value, long timeout);
/**
* 设置缓存
*
* @category 设置缓存
* @param key
* @param value
* @param expireAt
* ms
*/
public <T> void setExpireAt(String key, T value, long expireAt);
/**
* 获取缓存
*
* @category 获取缓存
* @param key
* @return Object 缓存对象
*/
public <T> T get(String key);
/**
* 使某个缓存过期
*
* @category 使某个缓存过期
* @param key
* @param timeout
* @return T 缓存对象
*/
public boolean expire(String key, long timeout);
/**
* 使得某个缓存在某个时刻过期
*
* @category 使得某个缓存在某个时刻过期
* @param key
* @param expireAt
*/
public boolean expireAt(String key, long expireAt);
/**
* 判断某个缓存是否存在
*
* @category 判断某个缓存是否存在
* @return boolean
*/
public boolean exist(String key);
/**
* 删除缓存
*
* @category 删除缓存
* @return boolean
*/
public boolean del(String key);
/**
* 添加key 的list数据缓存
* @return: void
* @throws
*/
public <T> void ladd(String key, T value);
/**
* 获得 key 的list数据缓存
* @throws
*/
public List<LogObject> list(String key);
}
EhcacheDefaultCache 为了以后拓展多个Ehcache方案
package com.seryo.cache;
/**
* 只为了获得类名称对应配置文件与 ehcache.xml中 name = "EhcacheDefaultCache" 相同
* @Package com.seryo.cache
* @ClassName: EhcacheDefaultCache
* @author hjj
*/
public class EhcacheDefaultCache extends EhcacheCache {
}
4.调用接口CacheFactory
package com.seryo.cache;
import com.seryo.util.StringUtils;
public class CacheFactory {
public static final String REDIS = "redis";
public static final String EHCACHE_DEFAULT_CACHE = "ehcache_default_cache";
public static Cache build(String key) {
if (StringUtils.isBlank(key)) {
throw new RuntimeException("不存在的缓存工具");
}
if (key.equalsIgnoreCase(REDIS)) {
return new RedisCache();
} else if(key.equalsIgnoreCase(EHCACHE_DEFAULT_CACHE)){
return new EhcacheDefaultCache();
}else{
throw new RuntimeException("不存在的缓存工具");
}
}
}
5.调用方法
Cache cache = CacheFactory.build(CacheFactory.EHCACHE_DEFAULT_CACHE);// 缓存对象
cache.del(KEY);// 删除验证码
cache.set(KEY, 数据, 时间);// 验证成功存放,验证数据
ehcache-core-2.4.3.jar 包
MyCacheEventListenerFactory 类(忘记放上来了)
package com.seryo.cache;
import java.util.Properties;
import net.sf.ehcache.event.CacheEventListener;
import net.sf.ehcache.event.CacheEventListenerFactory;
/**
* Event监听工厂
* @Package com.seryo.cache
* @ClassName: MyCacheEventListenerFactory
* @author hjj
* @date 2018年7月24日 下午2:13:10
*/
public class MyCacheEventListenerFactory extends CacheEventListenerFactory {
@Override
public CacheEventListener createCacheEventListener(Properties properties) {
return MyCacheEventListener.INSTANCE;
}
}