EJB3.0_方法缓存

公司维护的系统,涉及好多权限管理,区域信息,公共配置信息,之前系统都是通过缓存去读取这些配置信息,现在为了满足定制,开发了各种管理功能,这样就导致之前从缓存中读取的信息无法取到最新。

 

于是考虑用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,大家觉的,有哪些地方需要改进的?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值