`
Linuxboy
  • 浏览: 76953 次
  • 来自: ...
社区版块
存档分类
最新评论

转载:Tapestry5: Caching Method Results

阅读更多

Tapestry5: Caching Method Results

Assume you have methods that (almost) always return the same result for the same input arguments. If preparing method result is a heavy operation and/or it consumes time, it is reasonable to cache these results.

One way of building method cache in Tapestry5 is by implementing MethodAdvice interface like this:

public class CacheMethodResultAdvice implements MethodAdvice {

    private static final Logger logger = LoggerFactory.getLogger(CacheMethodResultAdvice.class);
    
    private final Cache cache;
    private final Class<?> advisedClass;
    private final Object nullObject = new Object();
    
    public CacheMethodResultAdvice(Class<?> advisedClass, Cache cache) {
        this.advisedClass = advisedClass;
        this.cache = cache;
    }
    
    @Override
    public void advise(Invocation invocation) {
        String invocationSignature = getInvocationSignature(invocation);
        
        String entityCacheKey = String.valueOf(invocationSignature.hashCode());

        Object result;
        
        if (cache.containsKey(entityCacheKey))
        {
            result = cache.get(entityCacheKey);

            logger.debug("Using invocation result ({}) from cache '{}'", invocationSignature, result);

            invocation.overrideResult(result);
        }
        else 
        {
            invocation.proceed();
            
            if (!invocation.isFail())
            {
                result = invocation.getResult();
                
                cache.put(entityCacheKey, result);
            }
        }
    }

    private String getInvocationSignature(Invocation invocation) {
        StringBuilder builder = new StringBuilder(150);
        builder.append(advisedClass.getName());
        builder.append('.');
        builder.append(invocation.getMethodName());
        builder.append('(');
        for (int i = 0; i < invocation.getParameterCount(); i++) {
            if (i > 0) {
                builder.append(',');
            }
            Class<?> type = invocation.getParameterType(i);
            builder.append(type.getName());
            builder.append(' ');

            Object param = invocation.getParameter(i);
            builder.append(param != null ? param : nullObject);
        }
        builder.append(')');
        
        return builder.toString();
    }
    
}
 Implementation of getInvocationSignature(...) is not ideal, but you may improve it to match your requirements. One issue I see here is building invocation signature for null-value parameters in a clustered environment (which is GAE). In this implementation method nullObject.toString() will return something like java.lang.Object@33aa9b. And this value will vary in different instances of your application. You may replace nullObject with just "null" string. Just keep in mind that "null" != null.

To make this advice working you should declare it in your AppModule.java:
@SuppressWarnings("unchecked")
    @Match("IPResolver")
    public static void adviseCacheIPResolverMethods(final MethodAdviceReceiver receiver, Logger logger, PerthreadManager perthreadManager) {
        try {
            Map props = new HashMap();

            //  IP address of URL may change, keep it in cache for one day
            props.put(GCacheFactory.EXPIRATION_DELTA, 60 * 60 * 24);
            
            CacheFactory cacheFactory = CacheManager.getInstance().getCacheFactory();
            Cache cache = cacheFactory.createCache(props);
            
            LocalMemorySoftCache cache2 = new LocalMemorySoftCache(cache);
            
            //  We don't want local memory cache live longer than memcache
            //  Since we don't have any mechanism to set local cache expiration
            //  we will just reset this cache after each request
            perthreadManager.addThreadCleanupListener(cache2);
            
            receiver.adviseAllMethods(new CacheMethodResultAdvice(IPResolver.class, cache2));
        } catch (CacheException e) {
            logger.error("Error instantiating cache", e);
        }
    }

    @Match("LocationResolver")
    public static void adviseCacheLocationResolverMethods(final MethodAdviceReceiver receiver, Cache cache) {
        //  Assume that location of IP address will never change, 
        //  so we don't have to set any custom cache expiration parameters
        receiver.adviseAllMethods(new CacheMethodResultAdvice(LocationResolver.class, cache));
    } 
 These declarations tell Tapestry5 to add our advice to all methods of services that implement IPResolver andLocationResolver interfaces. 

Note that we able to use caches with different settings for different methods/services like in example above (see comments in code).

See also:

分享到:
评论

相关推荐

    Tapestry 5开发指南(英文)

    Tapestry 5是一款强大的Java Web应用程序框架,由Apache软件基金会维护。它提供了一种声明式编程模型,使得开发者能够创建动态、响应式的Web应用,同时保持代码的整洁和易于维护。本指南将深入探讨Tapestry 5的核心...

    Tapestry 5 Project 5.0.16 API

    **Tapestry 5 Project 5.0.16 API** Tapestry 5 是一个强大的、基于Java的Web应用程序框架,由Apache..."Tapestry5.chm" 文件很可能是该API的离线帮助文件,包含详细的类库参考和示例,对于学习和开发工作非常有价值。

    Tapestry5开发文档.doc

    【Tapestry5开发文档】深入解析 Apache Tapestry 是一个强大的Java Web应用程序框架,它以组件为中心,为开发者提供了一种高效、易用且高度模块化的开发方式。Tapestry5版本带来了许多改进和增强,包括更好的性能、...

    Tapestry_5[1].1_实例教程

    Tapestry 5是一个开源的、基于组件的MVC框架,它提供了丰富的功能,使得开发人员能够更高效、更简洁地构建动态、高性能的Web应用。 在Tapestry 5.1版本中,主要包含以下几个核心知识点: 1. **组件模型**:...

    Tapestry-3.0.rar

    Tapestry 3.0是该框架的一个早期版本,尽管现在可能已被更现代的版本如Tapestry 5或6所取代,但了解其基础知识仍对理解Web开发的历史和技术演进有所帮助。 在Tapestry 3.0中,主要知识点包括: 1. **组件模型**:...

    tapestry最基本jar包

    5. **依赖注入**:Tapestry集成了依赖注入(DI)机制,支持Spring和其他兼容的DI容器。这使得服务和组件之间的关系更加松耦合,方便进行单元测试和重构。 6. **自动错误检测和调试**:Tapestry提供了一流的错误检测...

    Tapestry通用WEB框架

    5. **页面生命周期**:Tapestry定义了页面从初始化到销毁的完整生命周期。每个页面都有一个对应的Java类,该类在页面加载、提交表单等操作时被实例化和调用。 6. **切换皮肤**:在Tapestry中,可以轻松实现皮肤的...

    tapestry5.2.6 jar包

    5. **持久层集成**:Tapestry与Hibernate等ORM框架无缝集成,简化了数据库操作,如tapestry-hibernate模块,它提供了对Hibernate的支持。 6. **Spring集成**:通过tapestry-spring模块,Tapestry可以与Spring框架...

    tapestry4.1.6

    5. **强大的错误处理**:Tapestry 提供了优雅的错误处理机制,可以捕获和报告异常,提供友好的用户反馈,而不是显示默认的服务器错误页面。 6. **国际化与本地化**:Tapestry 支持多语言应用,可以轻松地切换不同的...

    tapestry5 build web application-alexander

    《Tapestry 5:构建Web应用程序》是关于Tapestry 5框架的一本权威指南。Tapestry 5是一个强大的Java Web应用框架,由Apache软件基金会开发并维护,它致力于提供一种更高效、更优雅的方式来构建动态、交互式的Web应用...

    Tapestry5和jQuery集成tapestry5-jquery.zip

    Tapestry5和jQuery集成.使用jQuery以极少的兼容问题完全替换Prototype 和 Scriptaculous库 标签:tapestry5

    Tapestry

    5. **模板语言**:Tapestry使用一种基于HTML的模板语言,允许开发者将标记和逻辑分离,保持视图的清晰性。 6. **依赖注入**:Tapestry支持依赖注入(DI),使得组件之间可以轻松地共享服务和数据,而无需手动创建...

    tapestry官方中文文档

    Tapestry是一款强大的Java Web应用程序框架,由Apache软件基金会维护,它强调了组件化、模块化和可重用性,使得开发复杂的Web应用变得更加简单。本文将深入介绍Tapestry 4的相关知识点。 1. **组件化编程**: ...

    Tapestry5, Packt.Publishing.Tapestry.5.Building.Web.Applications.Jan.2008.RETAiL.eBOOk-sUppLeX.pdf

    ### Tapestry5:构建Web应用程序 #### 一、Tapestry5概述 Tapestry5是一种先进的、基于Java的Web开发框架,它以其强大的功能、灵活性以及易用性著称。该框架由Howard Lewis Ship创建,并由Apache软件基金会维护。...

    Tapestry 5.1 实例教程(全部)

    5. **模版语言**:Tapestry使用一种基于HTML的模板语言,它允许在HTML中直接插入Java代码。理解模板元素、属性、条件语句和循环结构。 6. **Ajax支持**:Tapestry提供了内置的Ajax支持,使你能够创建富客户端界面。...

    Tapestry5.0.7

    1. **组件化编程**:Tapestry 5 强调组件化,每个页面元素都可以被看作是一个独立的组件,这使得代码可重用性大大提高,同时降低了复杂性。组件可以是简单的HTML元素,也可以是复杂的交互逻辑封装。 2. **模版语言*...

    tapestry 5 ..........

    ### 关于Tapestry 5的关键知识点 #### 1. 什么是Tapestry? Tapestry是一个开源框架,用于创建动态、稳健且高度可扩展的Java Web应用程序。它补充并建立在标准Java Servlet API之上,因此可以在任何Servlet容器或...

    Tapestry4开发指南.rar

    《Tapestry4开发指南》是一份针对Tapestry 4框架的详尽教程,旨在帮助开发者深入理解和熟练运用这一强大的Web应用开发工具。Tapestry是一个开源的Java框架,由Apache软件基金会维护,它提供了组件化、MVC模式以及...

    Tapestry5BuildingWebApplications

    ### Tapestry5构建Web应用程序:Java Web开发指南 #### 一、Tapestry5简介与特点 Tapestry5是一款由Apache基金会维护和支持的开源Java Web应用框架。它旨在简化Web应用的开发过程,通过其独特的组件化模型,提供了...

    Tapestry5最新中文入门实例教程

    ### Tapestry5最新中文入门实例教程 #### 一、引言 Tapestry是一个使用Java语言创建Web应用程序的面向组件的开发框架。本教程旨在通过实际案例帮助读者掌握Tapestry 5的基本概念和核心功能,并体验其带来的高效开发...

Global site tag (gtag.js) - Google Analytics