Tapestry的Cache组件 (转)

原创 Tapestry的Cache组件 (转)

有许多页面的一部分或者这个页面是很少更新的,他们通常是由外部文件来生成这个部分。所以我们可以把这部分内容cache住,当有新的请求时,我们就response cache,这样可以减少服务器的负担,还可以提高性能。其中oscache已经可以实现页面的cache和页面部分cache。oscache使用jsp tags来实现局部cache的。拿到Tapestry中肯定是行不通的。在同事的提醒下,想到写这个Tapestry的cache组件来达到重用的目的。

说干就干,先在头脑中想好要怎样使用cache(页面上的布局)。ok。 我想好了。

xml 代码
  1. <span jwcid="@Cache" cacheProvider="ognl:cacheProvider" updateCondition="ognl:needUpdate">
  2. //Cache body, which is the content you want to cache.
  3. <!--span>


这里有2个参数,updateCondition 当为true时,我们就绕过cache, cacheProvider 我把他定义为一个接口,这样用户可以把cache存在任何地方。而且提供这样的一个接口,用户可以更好的操作cache。先看看jwc对cache组件的定义。

xml 代码
  1. xml version="1.0" encoding="UTF-8"?>
  2. "-//Apache Software Foundation//Tapestry Specification 4.0//EN"
  3. "http://jakarta.apache.org/tapestry/dtd/Tapestry_4_0.dtd">
  4. <component-specification allow-body="yes" allow-informal-parameters="no" class="com.live.spaces.dengyin2000.tapestry.tfancomponents.components.Cache">
  5. <description>
  6. Cache component, this component can inclue any content as its body, and cache its body.
  7. This is useful in rarely updated content.
  8. <!--description>
  9. <parameter name="updateCondition" required="no" default-value="false">
  10. <description>
  11. The flag that need to refresh cache, it would casue tapestry render not use the cache.
  12. <!--description>
  13. <!--parameter>
  14. <parameter name="cacheProvider" required="yes">
  15. <description>
  16. You need to provider an cache provider to store its body content. for some simply use.
  17. Please see @com.live.spaces.dengyin2000.tapestry.tfancomponents.components.SimpleHtmlSourceCacheProvider
  18. <!--description>
  19. <!--parameter>
  20. <!--component-specification>


下面的是ICacheProvider接口:

java 代码
  1. package com.live.spaces.dengyin2000.tapestry.tfancomponents.components;
  2. /**
  3. * @author Denny - deng.yin@gmail.com
  4. * @since 2006-12-21
  5. */
  6. public interface ICacheProvider {
  7. /**
  8. *
  9. * @param cacheKey
  10. * @param cacheContent
  11. */
  12. public void storeCache(String cacheKey, String cacheContent);
  13. /**
  14. *
  15. * @param cacheKey
  16. * @return
  17. */
  18. public String getCacheContent(String cacheKey);
  19. /**
  20. * This method provider to user, so that user can controll cache manaully.
  21. * @param cacheKey
  22. */
  23. public void removeCache(String cacheKey);
  24. /**
  25. * This method provider to user, so that user can controll cache manaully.
  26. * Clear all caches
  27. *
  28. */
  29. public void reset();
  30. }


ok。 再来看看Cache组件的代码。

java 代码
  1. package com.live.spaces.dengyin2000.tapestry.tfancomponents.components;
  2. import java.io.PrintWriter;
  3. import java.io.StringWriter;
  4. import org.apache.commons.logging.Log;
  5. import org.apache.commons.logging.LogFactory;
  6. import org.apache.tapestry.AbstractComponent;
  7. import org.apache.tapestry.IMarkupWriter;
  8. import org.apache.tapestry.IRequestCycle;
  9. import org.apache.tapestry.util.ContentType;
  10. /**
  11. * @author Denny deng
  12. *
  13. */
  14. public abstract class Cache extends AbstractComponent {
  15. protected static final Log logger = LogFactory.getLog(Cache.class);
  16. public abstract boolean getUpdateCondition();
  17. public abstract ICacheProvider getCacheProvider();
  18. @Override
  19. protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle) {
  20. if (getUpdateCondition()){
  21. renderComponentWithCache(writer, cycle);
  22. }else{
  23. if (getCacheProvider().getCacheContent(this.getIdPath()) != null){
  24. //response cache html content.
  25. writer.printRaw(getCacheProvider().getCacheContent(this.getIdPath()));
  26. }else{
  27. renderComponentWithCache(writer, cycle);
  28. }
  29. }
  30. }
  31. private void renderComponentWithCache(IMarkupWriter writer, IRequestCycle cycle) {
  32. logger.debug("We need to refresh cache now.");
  33. CacheWriterWrapper cacheWrapper = new CacheWriterWrapper();
  34. super.renderBody(buildCacheMarkupWriter(cacheWrapper.getPrintWriter(), writer), cycle);
  35. String cacheContent = cacheWrapper.getCacheContent();
  36. logger.debug("fetched cache content, ready to put it into cache.");
  37. getCacheProvider().storeCache(this.getIdPath(), cacheContent);
  38. // response html content.
  39. writer.printRaw(cacheContent);
  40. }
  41. private IMarkupWriter buildCacheMarkupWriter(PrintWriter writer, IMarkupWriter sourceWriter){
  42. return this.getPage().getRequestCycle().getInfrastructure().getMarkupWriterSource().newMarkupWriter(writer, new ContentType(sourceWriter.getContentType()));
  43. }
  44. class CacheWriterWrapper{
  45. private StringWriter sw;
  46. private PrintWriter pw;
  47. public CacheWriterWrapper() {
  48. sw = new StringWriter();
  49. pw = new PrintWriter(sw);
  50. }
  51. public String getCacheContent(){
  52. return sw.getBuffer().toString();
  53. }
  54. public PrintWriter getPrintWriter(){
  55. return pw;
  56. }
  57. }
  58. }

主要是得到cache组件body的内容,然后把body的内容cache住,下次的话就response Cache的内容。 其实也是满简单的。

我自己还写了一个简单CacheProvider。

java 代码
  1. package com.live.spaces.dengyin2000.tapestry.tfancomponents.components;
  2. import java.util.HashMap;
  3. import java.util.Map;
  4. /**
  5. * @author Denny - deng.yin@gmail.com
  6. * @since 2006-12-21
  7. */
  8. public class SimpleHtmlSourceCacheProvider implements ICacheProvider {
  9. private Mapnew HashMap
  10. public String getCacheContent(String cacheKey) {
  11. return cache.get(cacheKey);
  12. }
  13. public void storeCache(String cacheKey, String cacheContent) {
  14. cache.put(cacheKey, cacheContent);
  15. }
  16. public void removeCache(String cacheKey) {
  17. cache.remove(cacheKey);
  18. }
  19. public void reset() {
  20. cache.clear();
  21. }
  22. }

在使用中你可以把CacheProvider放到Global或者Visit对象中。注意要使用同一个CacheProvider。

我在google code host上面建了一个probject地址是http://code.google.com/p/tfancomponents/ 有兴趣的同学可以看看, 这是一个maven项目。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/12467/viewspace-148272/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/12467/viewspace-148272/

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值