有许多页面的一部分或者这个页面是很少更新的,他们通常是由外部文件来生成这个部分。所以我们可以把这部分内容cache住,当有新的请求时,我们就response cache,这样可以减少服务器的负担,还可以提高性能。其中oscache已经可以实现页面的cache和页面部分cache。oscache使用jsp tags来实现局部cache的。拿到Tapestry中肯定是行不通的。在同事的提醒下,想到写这个Tapestry的cache组件来达到重用的目的。
说干就干,先在头脑中想好要怎样使用cache(页面上的布局)。ok。 我想好了。
//Cache body, which is the content you want to cache.
这里有2个参数,updateCondition 当为true时,我们就绕过cache, cacheProvider 我把他定义为一个接口,这样用户可以把cache存在任何地方。而且提供这样的一个接口,用户可以更好的操作cache。先看看jwc对cache组件的定义。
<!---->
"-//Apache Software Foundation//Tapestry Specification 4.0//EN"
"http://jakarta.apache.org/tapestry/dtd/Tapestry_4_0.dtd">
<component-specification allow-body="yes" allow-informal-parameters="no" class="com.live.spaces.dengyin2000.tapestry.tfancomponents.components.Cache">
<description>
Cache component, this component can inclue any content as its body, and cache its body.
This is useful in rarely updated content.
</description>
<parameter name="updateCondition" required="no" default-value="false">
<description>
The flag that need to refresh cache, it would casue tapestry render not use the cache.
</description>
</parameter>
<parameter name="cacheProvider" required="yes">
<description>
You need to provider an cache provider to store its body content. for some simply use.
Please see @com.live.spaces.dengyin2000.tapestry.tfancomponents.components.SimpleHtmlSourceCacheProvider
</description>
</parameter>
</component-specification>
下面的是ICacheProvider接口
public interface ICacheProvider {
/**
*
* @param cacheKey
* @param cacheContent
*/
public void storeCache(String cacheKey, String cacheContent);
/**
*
* @param cacheKey
* @return
*/
public String getCacheContent(String cacheKey);
/**
* This method provider to user, so that user can controll cache manaully.
* @param cacheKey
*/
public void removeCache(String cacheKey);
/**
* This method provider to user, so that user can controll cache manaully.
* Clear all caches
*
*/
public void reset();
}
ok。 再来看看Cache组件的代码。
public abstract class Cache extends AbstractComponent {
protected static final Log logger = LogFactory.getLog(Cache.class);
public abstract boolean getUpdateCondition();
public abstract ICacheProvider getCacheProvider();
@Override
protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle) {
if (getUpdateCondition()){
renderComponentWithCache(writer, cycle);
}else{
if (getCacheProvider().getCacheContent(this.getIdPath()) != null){
//response cache html content.
writer.printRaw(getCacheProvider().getCacheContent(this.getIdPath()));
}else{
renderComponentWithCache(writer, cycle);
}
}
}
private void renderComponentWithCache(IMarkupWriter writer, IRequestCycle cycle) {
logger.debug("We need to refresh cache now.");
CacheWriterWrapper cacheWrapper =new CacheWriterWrapper();
super.renderBody(buildCacheMarkupWriter(cacheWrapper.getPrintWriter(), writer), cycle);
String cacheContent = cacheWrapper.getCacheContent();
logger.debug("fetched cache content, ready to put it into cache.");
getCacheProvider().storeCache(this.getIdPath(), cacheContent);
// response html content.
writer.printRaw(cacheContent);
}
private IMarkupWriter buildCacheMarkupWriter(PrintWriter writer, IMarkupWriter sourceWriter){
return this.getPage().getRequestCycle().getInfrastructure().getMarkupWriterSource().newMarkupWriter(writer, new ContentType(sourceWriter.getContentType()));
}
class CacheWriterWrapper{
private StringWriter sw;
private PrintWriter pw;
public CacheWriterWrapper() {
sw = new StringWriter();
pw = new PrintWriter(sw);
}
public String getCacheContent(){
return sw.getBuffer().toString();
}
public PrintWriter getPrintWriter(){
return pw;
}
}
}
主要是得到cache组件body的内容,然后把body的内容cache住,下次的话就response Cache的内容。 其实也是满简单的。
我自己还写了一个简单CacheProvider。
public class SimpleHtmlSourceCacheProvider implements ICacheProvider {
private Map<string, string=""> cache = new HashMap<string, string="">();
public String getCacheContent(String cacheKey) {
return cache.get(cacheKey);
}
public void storeCache(String cacheKey, String cacheContent) {
cache.put(cacheKey, cacheContent);
}
public void removeCache(String cacheKey) {
cache.remove(cacheKey);
}
public void reset() {
cache.clear();
}
}
在使用中你可以把CacheProvider放到Global或者Visit对象中。注意要使用同一个CacheProvider。
我在google code host上面建了一个probject地址是http://code.google.com/p/tfancomponents/ 有兴趣的同学可以看看, 这是一个maven项目。
分享到:
相关推荐
Tapestry API提供了`Component`接口和相关的实现类,例如`Page`和`ComponentTemplate`,用于构建这些组件。 2. **MVC架构** 在Tapestry中,模型、视图和控制器的概念得到了清晰的体现。`Model`代表数据和业务逻辑...
- **osCache组件**:包括缓存管理器(Cache Manager)、缓存(Cache)、缓存项(Cache Item)等核心组件,提供了缓存的创建、管理和操作功能。 2. **osCache的配置**: - `osCache`可以通过XML配置文件进行配置,...
- Tapestry:强调类型安全和组件重用。 - Wicket:基于组件的Web框架,注重开发者友好。 - Apusic OperaMasks:国内首款JSF引擎,适合本地化开发。 2. **持久层框架**: - Hibernate:流行的ORM框架,简化了与...
wangtengfei-hn_EmployeesExample_23540_1745868671962
scratch少儿编程逻辑思维游戏源码-汽车冲突.zip
scratch少儿编程逻辑思维游戏源码-棱镜.zip
少儿编程scratch项目源代码文件案例素材-直升机坠毁.zip
输入法优化与定制_五笔编码编辑与词库管理_Rime输入法引擎与86极点码表_跨平台五笔码表编辑器工具_for_macOS与Windows系统_支持用户自定义词条添加删除与排序_提供
少儿编程scratch项目源代码文件案例素材-主题乐园大亨.zip
scratch少儿编程逻辑思维游戏源码-迷失在像素平原.zip
少儿编程scratch项目源代码文件案例素材-纸格通关 云变量.zip
wanjunshe_Python-Tensorflow_12888_1745868924470
scratch少儿编程逻辑思维游戏源码-深入海底.zip
驾校自动化_网页自动化爬虫技术_Python27多线程HTTP请求模拟_龙泉驾校2014版约车系统自动预约助手_通过模拟登录和循环请求实现自动约车功能_支持失败自动递增车号重试_
scratch少儿编程逻辑思维游戏源码-南瓜危机.zip
scratch少儿编程逻辑思维游戏源码-皮博冒险者.zip
基于c++开发的网络嗅探器,重点对TCP、UDP、ARP、IGMP、ICMP 等数据包进行分析,实现捕捉前过滤、数据包统计、流量统计等功能+源码+项目文档,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用,详情见md文档 基于c++开发的网络嗅探器,重点对TCP、UDP、ARP、IGMP、ICMP 等数据包进行分析,实现捕捉前过滤、数据包统计、流量统计等功能+源码+项目文档,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用,详情见md文档~ 基于c++开发的网络嗅探器,重点对TCP、UDP、ARP、IGMP、ICMP 等数据包进行分析,实现捕捉前过滤、数据包统计、流量统计等功能+源码+项目文档,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用,详情见md文档 基于c++开发的网络嗅探器,重点对TCP、UDP、ARP、IGMP、ICMP 等数据包进行分析,实现捕捉前过滤、数据包统计、流量统计等功能+源码+项目文档,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用,详情见md文档 基于c++开发的网络嗅探器,重点对TCP、UDP、ARP、IGMP、ICMP 等数据包进行分析,实现捕捉前过滤、数据包统计、流量统计等功能+源码+项目文档,适合毕业设计、课程设计、项目开发。项目源码已经过严格测试,可以放心参考并在此基础上延申使用,详情见md文档
用于释放电脑的内存,很好用。
scratch少儿编程逻辑思维游戏源码-气球足球.zip
ollama 0.6.6.0官网下载,不方便的可以从这里下载