公司维护的系统,涉及好多权限管理,区域信息,公共配置信息,之前系统都是通过缓存去读取这些配置信息,现在为了满足定制,开发了各种管理功能,这样就导致之前从缓存中读取的信息无法取到最新。
于是考虑用Ehcache来实现方法缓存,这个在spring 中整合是非常简单的,这边考虑在Ejb3中整合Ehcache。
废话不说,直接代码,demo 如下:
定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Cache
{
public CacheFlag value();
}
定义注解取值
public enum CacheFlag
{
/**
* 添加缓存
*/
ADD,
/**
* 删除缓存
*/
DELETE
}
缓存处理实例
/**
* Ehcache Handler
*
* @author
* @version [版本号, 2011-3-13]
* @see [相关类/方法]
* @since [产品/模块版本]
*/
public class CacheHandler
{
/**
* 实例
*/
public volatile static CacheHandler cacheHandler = null;
/**
* cache 名称
*/
private static final String CACHE_NAME = "methodCache";
private CacheManager cacheManager = null;
private net.sf.ehcache.Cache cache = null;
private boolean status = false;
private static Map<String, List<String>> ADDCACHEMAP =
new HashMap<String, List<String>>();
private static Map<String, List<String>> DELETECACHEMAP =
new HashMap<String, List<String>>();
private CacheHandler()
{
initCache();
}
private void initCache()
{
cacheManager = new CacheManager(Thread.currentThread()
.getContextClassLoader()
.getResourceAsStream("conf/cache/ehcache.xml"));
cache = cacheManager.getCache(CACHE_NAME);
if (null != cache)
{
status = true;
}
}
public void checkCacheStatus(Method method)
{
String className = method.getDeclaringClass().toString();
List<String> localStatus = ADDCACHEMAP.get(className);
if (null == localStatus)
{
initCacheForClass(method); // 初始化
}
}
/**
* 初始化缓存
* @param method
* Method
* @return void [返回类型说明]
* @exception throws [违例类型] [违例说明]
* @see [类、类#方法、类#成员]
*/
private void initCacheForClass(Method method)
{
List<String> methodCache = null;
String methodInfo = null;
String className = method.getDeclaringClass().toString();
Method[] arrayOfMethod = method.getDeclaringClass().getMethods();
for (Method med : arrayOfMethod)
{
com.xxx.util.cache.Cache cacheAnnotation = med.getAnnotation(com.xxx.util.cache.Cache.class);
if (null != cacheAnnotation)
{
if (cacheAnnotation.value().equals(CacheFlag.ADD))
{
methodCache = ADDCACHEMAP.get(method.getDeclaringClass().toString());
if (null == methodCache)
{
methodCache = new ArrayList<String>();
ADDCACHEMAP.put(className, methodCache);
}
methodInfo = med.getName() + ":" + Arrays.toString(med.getParameterTypes());
methodCache.add(methodInfo);
}
else if (cacheAnnotation.value().equals(CacheFlag.DELETE))
{
methodCache = DELETECACHEMAP.get(method.getDeclaringClass().toString());
if (null == methodCache)
{
methodCache = new ArrayList<String>();
DELETECACHEMAP.put(className, methodCache);
}
methodInfo = med.getName() + ":" + Arrays.toString(med.getParameterTypes());
methodCache.add(methodInfo);
}
}
}
}
/**
* 获取 Cache key
* @param className
* @param methodName
* @param paramArrayOfObject
* @return [参数说明]
*
* @return String [返回类型说明]
* @exception throws [违例类型] [违例说明]
* @see [类、类#方法、类#成员]
*/
protected String getCacheKey(String className, String methodName,
Object[] paramArrayOfObject)
{
StringBuffer cacheKey = new StringBuffer();
cacheKey.append(className).append(".").append(methodName);
if ((paramArrayOfObject != null) && (paramArrayOfObject.length != 0))
{
for (int i = 0; i < paramArrayOfObject.length; ++i)
{
if (paramArrayOfObject[i] != null)
{
cacheKey.append(".").append(getArgumentString(paramArrayOfObject[i]));
}
else
{
cacheKey.append(".null");
}
}
}
return cacheKey.toString();
}
@SuppressWarnings("unchecked")
private String getArgumentString(Object paramObject)
{
Class localClass = paramObject.getClass();
if (localClass.isArray())
{
if (localClass.isAssignableFrom(Integer.class))
{
return Arrays.toString((int[]) (int[]) paramObject);
}
if (localClass.isAssignableFrom(Boolean.class))
{
return Arrays.toString((boolean[]) (boolean[]) paramObject);
}
return Arrays.toString((Object[]) (Object[]) paramObject);
}
return paramObject.toString();
}
public boolean isCache(InvocationContext invocationContext)
{
Cache cacheFlag = invocationContext.getMethod().getAnnotation(Cache.class);
if (null != cacheFlag)
{
if (cacheFlag.value().equals(CacheFlag.ADD))
{
return true;
}
}
return false;
}
public boolean isClear(InvocationContext invocationContext)
{
Cache cacheFlag = invocationContext.getMethod().getAnnotation(Cache.class);
if (null != cacheFlag)
{
if (cacheFlag.value().equals(CacheFlag.DELETE))
{
return true;
}
}
return false;
}
public void clearCache()
{
net.sf.ehcache.Cache cache = cacheManager.getCache(CACHE_NAME);
cache.removeAll();
}
public static CacheHandler getInstance()
{
if (null == cacheHandler)
{
synchronized (CacheHandler.class)
{
if (null == cacheHandler)
{
cacheHandler = new CacheHandler();
}
}
}
return cacheHandler;
}
public boolean isEnable()
{
return status;
}
public synchronized void destroy()
{
cacheManager.shutdown();
status = false;
}
public Object getCacheElement(String cacheKey) throws CloneNotSupportedException
{
Element element = cache.get(cacheKey);
if (null != element)
{
return ((Element) element.clone()).getValue();
}
return null;
}
public void addResult(String cacheKey, Object cacheValue)
{
Element element = new Element(cacheKey, cacheValue);
this.cache.put(element);
}
}
EJB 拦截器定义
public class CacheInterceptor
{
@AroundInvoke
public Object cacheProcess(InvocationContext invocationContext) throws Exception
{
Object result = null;
CacheHandler cacheHandler = CacheHandler.getInstance();
if (cacheHandler.isEnable())
{
boolean isCache = cacheHandler.isCache(invocationContext);
boolean isClear = cacheHandler.isClear(invocationContext);
if (!isCache && !isClear)
{
result = invocationContext.proceed();
return result;
}
// 清空缓存
if (isClear)
{
cacheHandler.clearCache();
result = invocationContext.proceed();
return result;
}
if (isCache)
{
String className = invocationContext.getMethod().getDeclaringClass().getName();
String methodName = invocationContext.getMethod().getName();
Object[] paramArrayOfObject = invocationContext.getParameters();
// Cache key
String cacheKey = cacheHandler.getCacheKey(className,
methodName,
paramArrayOfObject);
try
{
result = cacheHandler.getCacheElement(cacheKey);
if (null == result)
{
result = invocationContext.proceed();
cacheHandler.addResult(cacheKey, result);
}
}
catch (Exception e)
{
result = invocationContext.proceed();
}
return result;
}
}
else
{
result = invocationContext.proceed();
return result;
}
return invocationContext.proceed();
}
}
EJB 方法使用
@Override
@Interceptors(CacheInterceptor.class)
@Cache(CacheFlag.ADD)
public CabinDomain queryCabinInfo(CabinPK cabinPK)
{
return entityManager.find(CabinDomain.class, cabinPK);
}
@Override
@Interceptors(CacheInterceptor.class)
@Cache(CacheFlag.DELETE)
public void addCabinInfo(CabinDomain cabinDomain)
{
entityManager.persist(cabinDomain);
}
其他:部署在Jboss上
简单的demo,大家觉的,有哪些地方需要改进的?