1.ehcache工具类
package com.ai.ecsite.ehcache.utils;
import com.ai.ecsite.util.common.SpringContextHolder;
import com.ai.ecsite.util.common.StringUtils;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Element;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.cache.ehcache.EhCacheCacheManager;
/**
* ehcache工具类
*
* Created by huxin on 2016/12/26.
*/
public class EhcacheUtils {
private final static Logger logger = LoggerFactory.getLogger(EhcacheUtils.class);
// 得到ehcache缓存管理器
private static EhCacheCacheManager ehCacheCacheManager;
// ehcache缓存管理器
private static CacheManager cacheManager;
/**
* 初始化工具类
*/
private EhcacheUtils(String configuration){
// 如果在spring中有配置ehcache,那么由spring托管
try {
ehCacheCacheManager = SpringContextHolder.getBean(EhCacheCacheManager.class);
} catch (Exception e) {
logger.warn("spring doesn't inject ehcache bean");
}
// 如果spring有托管ehcahce,那么由spring容器中得到ehcache管理器
if (ehCacheCacheManager != null){
cacheManager = ehCacheCacheManager.getCacheManager();
}else{
if (StringUtils.isNotEmpty(configuration)){
cacheManager = CacheManager.newInstance(configuration);
}else{
// 如果配置文件不为空
cacheManager = CacheManager.getInstance();
}
}
}
/**
* 初始化工具类
*/
private EhcacheUtils(){
new EhcacheUtils(null);
}
/**
* 得到工具类实例
*
* @return
*/
public static void initCacheManager(String configuration){
// 如果缓存工类灯为空
if (cacheManager == null){
// 如果指定了配置文件
new EhcacheUtils(configuration);
}
}
/**
* 得到工具类实例
*
* @return
*/
public static void initCacheManager(){
// 如果缓存工类灯为空
if (cacheManager == null){
initCacheManager(null);
}
}
/**
* 在指定的缓存中塞入需要缓存值
*
* @param cacheInstanceName 缓存实例名称
* @param key 缓存键
* @param cacheValue 缓存值
*/
public static void put (String cacheInstanceName, Object key, Object cacheValue){
if (cacheManager == null){
initCacheManager();
}
// 按缓存实例名取出一个缓存
Cache cache = cacheManager.getCache(cacheInstanceName);
// 如果待操作的缓存不存在,那么创建一个
if (cache == null){
// 创建缓存
cacheManager.addCache(cacheInstanceName);
cache = cacheManager.getCache(cacheInstanceName);
}
// 构建缓存键值到
Element element = new Element(key, cacheValue);
// 缓存信息置入缓存中
cache.put(element);
}
/**
* 从缓存实例中取出缓存信息
*
* @para cacheInstanceName 缓存实例名
* @param key 缓存键
* @return
*/
public static Object get (String cacheInstanceName, Object key){
if (cacheManager == null){
initCacheManager();
}
// 根据缓存实例名取出缓存信息
Cache cache = cacheManager.getCache(cacheInstanceName);
// 如果没有指定的缓存实例,返回空
if (cache == null){
logger.warn("cache instance doesn't exists!");
return null;
}
Element element = cache.get(key);
return element == null ? null : element.getObjectValue();
}
/**
* 删除缓存实例信息
*
* @param cacheInstanceName 缓存实例名称
* @return 操作结果 true-删除成功 false-删除失败
*/
public static boolean removeCacheInstance (String cacheInstanceName){
try {
// 如果ehcache管理器为空,那么实始化管理器实例
if (cacheManager == null){
initCacheManager();
}
// 缓存缓存实例
cacheManager.removeCache(cacheInstanceName);
return true;
} catch (IllegalStateException e) {
logger.error("remove cache instance error!", e);
}
return false;
}
/**
* 根据键删除指定缓存实例缓存
* @param cahceInstanceName ehcache实例名
* @param key 缓存键
*/
public static void remove (String cahceInstanceName, Object key){
if (cacheManager == null){
initCacheManager();
}
// 根据缓存实例名称得到缓存
Cache cache = cacheManager.getCache(cahceInstanceName);
// 如果缓存不为空,那么创建缓存实例
if (cache != null){
cache.remove(key);
}
}
/**
* 创建缓存实例
*
* @param cacheName 级存实例名称
* @param maxElementsInMemory 缓存实例存储最大元素数
* @param overflowToDisk 是否持久化到硬盘
* @param eternal 是否会自动死亡
* @param timeToLiveSeconds 最大生存时间,当external为true时有效
* @param timeToIdleSeconds 最大空闲时间,超过之后自动消亡,当external为true时有效
*
* @return 缓存实例对象
*/
public static Cache initCache(String cacheName, int maxElementsInMemory, boolean overflowToDisk, boolean eternal, long timeToLiveSeconds, long timeToIdleSeconds) throws Exception {
// 如果缓存管理理器未初始化
if (cacheManager == null){
initCacheManager();
}
try {
// 首先根据缓存实例的名称从理器里获取缓存信息
Cache myCache = cacheManager.getCache(cacheName);
// 如果缓存实例不存在
if (myCache == null) {
// 创建缓存实例
Cache memoryOnlyCache = new Cache(cacheName, maxElementsInMemory, overflowToDisk, eternal, timeToLiveSeconds, timeToIdleSeconds);
// 将缓存加入管理器中
cacheManager.addCache(memoryOnlyCache);
// 获取缓存
myCache = cacheManager.getCache(cacheName);
}
return myCache;
} catch (Exception e) {
logger.error("init cache " + cacheName + " failed!!!", e);
throw new Exception("创建缓存实例失败");
}
}
}
ehcache配置文件
| 配置项 | 描述 |
1 | name | 缓存名称 |
2 | maxElementsInMemory | 缓存元素的最大数 |
3 | eternal | 是否自动失效:true-自动失效;false-不自动失效 |
4 | timeToIdleSeconds | 空闲最大时间,当空闲时间超过设定时间后该元素失效,如果该属性设置为0,表示缓存的闲置时间无穷大,当eternal配置为true时有效 |
5 | timeToLiveSeconds | 最大有效时间,当超过设定时间后该元素失效,如果该属性设置为0,表示缓存的有效时间无穷大,当eternal配置为true时有效 |
6 | overflowToDisk | 当元素溢出时是否保存到硬盘 |
7 | diskSpoolBufferSizeMB | 置磁盘缓存区大小 |
8 | maxElementsOnDisk | 硬盘最大缓存个数 |
9 | diskPersistent | 否缓存虚拟机重启期数据,默认false |
10 | diskExpiryThreadIntervalSeconds | 磁盘失效线程运行时间间隔,默认120秒 |
11 | memoryStoreEvictionPolicy | 达到maxElementsInMemory限制时,Ehcache将会根据指 定的策略去清理内存,默认策略是LRU。 LRU:最近最少使用; FIFO:先进先出; LFU:较少使用。 |
12 | clearOnFlush | 内存数量最大时,是否清除 |
其详细配置见cache.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">
<!-- 默认缓存 -->
<defaultCache
maxElementsInMemory="1000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="false"/>
<cache name="test"
maxElementsInMemory="1000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="false"/>
</ehcache>
spring与ehcache集成
1. 将ehcache让spring进行统一管理,指定缓存管理器,以及缓存工厂
<cache:annotation-drivencache-manager="cacheManager"/>
<!-- cachefactory -->
<beanid="cacheManagerFactory"class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean">
<propertyname="configLocation">
<value>classpath:cache.xml</value>
</property>
</bean>
<bean id="cacheManager"class="org.springframework.cache.ehcache.EhCacheCacheManager">
<propertyname="cacheManager" ref="cacheManagerFactory"/>
</bean>
2. 用注解对缓存进行操作:
Ø Cacheable:用Cacheable注解标记的方法会在执行之后将结果缓存到ehcache中。Value指定缓存数据的缓存名称(在cache.xml中配置),key指定缓存数据的键,condition属性指定缓存动作发生的条件。缓存的键支持SpringEL表达式:
属性名称 | 描述 | 示例 |
methodName | 当前方法名 | #root.methodName |
method | 当前方法 | #root.method.name |
target | 当前被调用的对象 | #root.target |
targetClass | 当前被调用的对象的class | #root.targetClass |
args | 当前方法参数组成的数组 | #root.args[0] |
caches | 当前被调用的方法使用的Cache | #root.caches[0].name |
@Cacheable(value = "exceptionCache", key = "'sys_exception_cache'")
@Override
public Map<String, String> getData (){…}
Ø CacheEvict:用来标记需要清除缓存元素的方法或类上。
allEntries:表示是否需要清除缓存中的所有元素;
beforeInvocation:当该属性值为true时,在执行目标方法前清除缓存。
Ø Caching:可以在一个方法或类上同时指定多个SpringCache的相关注解
Ø CachePut:这个注释可以确保方法被执行,同时方法的返回值也被记录到缓存中