Tapestry 3.0 原理 简述

    最近几天看了Tapestry3.0源码,做个总结吧。

    从对象的角度来述说3.0的原理及她的架构思想,当然只是简单的总结述说。

ApplicationServlet

   继承 httpServlet类,主要创建每次具体访问所需的RequestContext。它生成了一个

Engine,并把这个 Engine存放一个session中,让所有的访问者共享,可以说 Engine是

一个真正持久量 。且对具体某次访问,可获得相应的Tapestry service 名字。也许会

问,为什么对于每次访问,它怎么知道对应的是哪种service呢?对于一个访问者,比

若访问一张页面,除了主页外(默认用HomeService),他要开始发起访问必须从该主页

中的某处,用Tapestry的概念来说,是必须从页面的某个Component处发动,显然各自

的Component指明了各自的service(见下面的Component说明),所以Engine 可以根据

服务名拿到每次具体访问者的service。当然,对于多用户,Engine使用一个数据结

构,来保存各个用户的某次具体访问的service,保证不会混搅起来。

RequestContext

     包装 HttpServletRequest  httpServletResponse ,也就是相当于JSP中的Response

和Request对象。cookie 什么的都可以在这里做,熟悉JSP 的会非常熟悉使用。

RequestContext还可以writing an HTML description of the RequestContext 。

      RequestContext由ApplicationServlet创建。

Engine

 Tapestry真正Web Application 。它获取Tapestry的具体某个service    ( 既然

RequestContext的具体实例,已经保存了service的名字,所以可以通过

requestcontext.getParameter("service")来得到 ) 。获取了服务名,Engine就可以提供

该服务。 Engine可以提供好几个服务,具体的服务对应着自己如何rewind/render来满

足客户的需求,当然它肯定会包装RequestCycle,从而达到rewind/render的目的。
 

     Engine因为是个持久量,所以用来存放像JSP 中Application对象那样的全局变量,

绝对是个不错的地方,Tapestry用了个新结构Global来实现这个概念,它就存在

Engine,也就是这个persistant-session当中。至于visit,其实我觉的不是很需要,你完

全可以用 requestContext.setAttribute()来进行保存的,Tapestry之所以设计了 这么一

个visit结构,可能是处于让用户忘记JSP,且用起来更加方便,更加 Tapestry化的目的

吧!?     

       Engine创建和管理pagepool和pagerecorde,用来实现各个客户访问页面的调度管

理。 Engine创造了RequestCycle,创建成的RequestCycle,明确包含了service,   用

它来实现Tapestry化的客户会话期间的具体请求功能,如requestCycle.getPage(String

pagename)来load一张页面。

   Engine还为每个客户请求建立输出流ResponseOutputStream,此流依靠httpservlet的

HttpServletResponse封装而来

 RequestCycle

    主要的作用是获取页面、绘制页面、Tracking changes to page properties、

Exception handling 和Pooling of page ,系统自动靠它才实现了rewind/render。这个和

前面的RequestContext非常的相似,都是在一个会话期间内的具体对象,随着会话创

建而创建、消亡而消亡。本来我想,不用在做这么个对象的,但是看作者的意图应该

把会话的请求功能做了一个划分,RequestContext主要针对类似 JSP 技术上的

Response和Request对象的作用,而RequestCycle则与会话内页面,以及Engine等相

互联系作用相关。或者也可以这么说,RequestContext是由ApplicationContext创建

的,对于某次客户request,我们很难在RequestContext中加点我们自己的什么的西,
 

而RequestCycle则不一样,它是有 Engine创建的,而且具体的Engine还要开发者自

己写,这样,我们很容易通过Engine让这次客户Request的时候做点我们想他做的,比

若 Engine的setpupForRequest和cleanupAfterRequest就可以对这个客户的在这次会话

期间内的 request做点什么东西了,这大大方便了开发者。

 Component

    提供一个URL,把Component 要实现的service 放到改URL中,以便于让用户发出请求

的时候,使得该URL被RequestContext所截获,我猜测该URL为这样的

http://xx.xx.xx/xx.html?service=xxxx,当然要变成这个样子是在该Component被render

后。
    

它还有其他的一些常用功能,比若getBinding(String name) ,getComponent(String id)等

等 ,或者到具体的某个Component可能会有trigger。Copmonet最终的目的是绘制成

HTML页面,但是在Tapestry中Componet是由模板构成的,这就需要一种方式把

Component 的模板形式转化为最终的 HTML形式,以便反馈给客户端的浏览器,这个

过程 Tapestry叫做rerend,当然这其中发生了setter/getter,假若没有发生setter/getter就

叫做rewind。因为Componet是由模板构成,模板并不是纯JAVA ,做setter/getter,要

借助于OGNL表达式语言来实现。

Page

  Page由Component组成,或者说,Page是放置Component的容器,可以把Page看

成是一个最大的 Component,注意detach和attach两个函数可以让页面联系到某个

Engine;通过getRequestCycle和setRequestCycle,页面可以和某次具体的

RequestCycle联系起来。

     怎么样load一张page呢

        RequestCycle的getPage(pagename) ====>Engine的getPageSource().getPage()

====>假如页面有一些Component复合而成====>

 page.getNestedComponent(componentPath) ====>page.getPage()

其中要判断page哪里来的和有无变化的property变化哪里来的,假如没有来之pool,则

要放进去。

   如何把这张页面输出给客户呢?

   Engine的 renderResponse() ====>通过ResponseOutputStream I/O 流用

page.getResponseWriter() 获取一个实iMarkupWriter =====>

requestcycle.renderPage(iMarkupWriter);

   以上 load和render就是一个EngineService所需提供的服务,Tapestry有好几个

服务,如HomeService、ActionService、DirectService 、PageService等等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值