`
smallsnake
  • 浏览: 7535 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

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

分享到:
评论
5 楼 pch272215690 2012-08-16  
pch272215690 写道
真实项目中用过吗?我最近也想搞个类似的,就是key生成方式没有想到。
这个好用我就不客气了。

其实我们已经用了。key的生成方式为:类名+方法名+参数的json格式表示,不过我已经辞职了,哈哈!
4 楼 smallsnake 2012-08-15  
winwa 写道
没有起到效果啊!还是每次都查询数据库了

恩,你将你的代码贴出来呢
3 楼 winwa 2012-08-03  
没有起到效果啊!还是每次都查询数据库了
2 楼 pch272215690 2012-02-02  
真实项目中用过吗?我最近也想搞个类似的,就是key生成方式没有想到。
这个好用我就不客气了。
1 楼 smallsnake 2011-03-23  
:D 针对大量的数据,可以写个公共的缓存的机制

相关推荐

    ejb3.0_persistence_doc

    "ejb3.0_persistence_doc"这个压缩包包含的文档和资料主要聚焦于EJB 3.0中的持久化特性,特别是通过`javax.persistence`包中的注解来实现的。 1. **Java Persistence API (JPA)**: JPA是Java EE平台的标准持久化...

    EJB3.0 简介

    ### EJB 3.0 简介及关键技术解析 #### 一、EJB 3.0 概览 EJB (Enterprise JavaBeans) 3.0 是 Java 企业级应用开发的重要里程碑,它简化了复杂的业务逻辑组件的开发过程,并引入了许多新的特性来提高开发效率和灵活...

    EJB3.0 实例编程

    EJB3.0通过容器管理的缓存、池化等技术,提升了组件的性能,同时提供了更细粒度的控制,如懒加载、批处理等,以便更好地优化应用程序。 10. **集成性** EJB3.0与JSF、Spring、Hibernate等其他Java框架很好地集成...

    精通EJB3.0源码,EJB3实例

    在"精通EJB3.0源码,书本《精通EJB3.0》的源码,EJB3实例"这个主题中,我们将深入探讨EJB3.0的关键特性、源码解析以及实例应用。 1. **EJB 3.0的主要改进**: - **注解驱动**:EJB 3.0引入了大量的注解,如`@Entity...

    EJB3.0规范中英文版合集

    4. **二级缓存**:EJB 3.0支持实体级别的缓存策略,提高数据访问性能。 5. **迁移与兼容性**:指导开发者如何从旧版本的持久化机制迁移到EJB 3.0的JPA。 通过这些文档,开发者可以全面理解EJB 3.0规范,熟练掌握...

    JBoss下EJB3.0实例教程(黎活明)

    - 注解驱动:EJB3.0引入了注解,使得开发者可以避免XML配置,直接在类或方法上使用注解声明bean的角色和行为。 - 容器管理的持久性(CMP):通过@PersistenceContext和@PersistenceUnit注解,容器自动管理实体bean的...

    浪曦_EJB3.0实例教程_多对多映射

    **EJB 3.0 实例教程:多对多映射** 在企业级Java应用开发中,Entity Bean(实体Bean)是核心组件之一,用于持久化业务数据。EJB 3.0是Java EE 5规范的一部分,它极大地简化了Bean的使用,包括对关系数据库的映射。...

    ejb3.0写的登陆应用

    EJB(Enterprise JavaBeans)...这个“ejb3.0写的登陆应用”涵盖了EJB 3.0的核心特性,展示了如何利用其优势构建一个简洁而有效的登录系统。通过深入理解和实践这些知识点,开发者能够更好地掌握Java企业级应用的开发。

    EJB3.0+JSF例子

    在"**EJB3.0+JSF例子**"教程中,你将学习如何结合使用这两种技术,创建一个完整的、功能丰富的Web应用程序。教程可能涵盖了从创建EJB Bean和JSF Managed Bean,到配置和部署应用,以及处理用户交互和事务处理的全...

    EJB 3.0 在 WAS V7 上开发部署的最佳实践

    4. **性能优化**:合理配置EJB的池大小、缓存策略以及资源管理,可以显著提升应用的性能。 5. **日志和调试**:充分利用WAS V7的日志和跟踪功能,可以帮助开发者在问题出现时快速定位和解决问题。 总的来说,成功...

    基于EJB3.0的分布式网上购物系统毕业设计.doc

    EJB是Java EE平台的核心组成部分,自1999年首次发布以来,经过多次版本迭代,EJB 3.0在2006年发布,显著简化了API,降低了开发复杂度,使得EJB更易用、更高效。 1.3 从WEB层访问EJB 在EJB 3.0中,可以通过Servlet...

    ejb3.0文档

    ### EJB 3.0 文档关键知识点解析 #### 标题:EJB 3.0 文档 **企业 Java Beans (EJB)** 是一种基于 Java 的组件模型,主要用于开发可扩展、健壮的企业级应用。EJB 3.0(也称为 EJB Lite)作为 EJB 规范的重大更新,...

    ejb3.0

    随着EJB 3.0中JPA的引入,Kodo成为了一个重要的选择,它不仅支持标准的JPA规范,还提供了许多高级功能,如缓存管理、性能优化等,从而帮助开发者构建高性能的企业级应用。 综上所述,EJB 3.0通过引入注解、业务接口...

    FromEJB2toEJB3

    - 考虑性能优化,例如EJB 3.0提供了更灵活的缓存和事务控制策略。 总结起来,EJB 3.0 的核心目标是简化EJB的开发和使用,提高开发效率。通过减少不必要的接口和类,引入注解和EntityManager API,使得EJB更接近普通...

    JPA操作手册,包括EJB3.0

    ### JPA操作手册与EJB3.0:深入解析及迁移指南 #### 一、概述 JPA(Java Persistence API)作为一种标准化的对象关系映射(ORM)技术,旨在为Java平台提供一个统一的数据持久化解决方案。它最初是在EJB3.0规范...

    Java Persistence API(EJB3.0中的 JPA 规范说明)

    - **规范制定者**:该规范由 Linda DeMichiel 和 Michael Keith 共同领导的 EJB3.0 Expert Group 制定。这两位专家分别来自 Sun Microsystems 和 Oracle Corporation。 - **许可证声明**:文档中明确指出提供了两种...

    ejb-3_0-fr-spec-persistence.pdf

    - **异步方法调用**:允许开发者定义异步EJB方法,提高系统的响应性和可伸缩性。 - **持久化**:通过JPA实现数据的持久化操作,支持多种数据库系统。 #### 技术要点详解 1. **EJB 3.0的新特性**: - **轻量级...

Global site tag (gtag.js) - Google Analytics