Tapestry3源码阅读笔记5:AbstractEngine/IEngineService
之前可以看出tapestry的servlet是调用engine的service方法来进行渲染页面的。这里来看engine类。
?
?
AbstractEngine类是继承engine接口的基本类,子类BaseEngine,一般业务使用的engine都是直接使用BaseEngine或者BaseEngine的子类。setupForRequest(context);monitor = getMonitor(context);output = new ResponseOutputStream(context.getResponse());?首先先为这次请求初始化一些基本信息setupForRequest。方法里会设置上这个engine的_pool/pageSource、servicemap等等基本变量。Page相关的的PageSource、Pool就是在这里初始化的。
serviceName = extractServiceName(context);?获取当前的serviceName
if (Tapestry.isBlank(serviceName)) serviceName = Tapestry.HOME_SERVICE;?如果找不到servicename,那么默认的servicename为homeservice。
// Must have a service to create the request cycle.// Must have a request cycle to report an exception.service = getService(serviceName);//获取到EngineService。cycle = createRequestCycle(context, service, monitor);//为这次请求建立requestcyclemonitor.serviceBegin(serviceName, context.getRequestURI());// Invoke the service, which returns true if it may have changed// the state of the engine (most do return true).service.service(this, cycle, output);?这里根据servicename获取到IEngineService。然后调用它的service方法进行渲染页面。
上述的serviceName为app?service=page/List&listener=initPage这样的字符串后service=page里的page。然后根据page去servicemap里查找对应的servic。servicemap是在setupForRequest方法里进行初始化的,它会根据全局的配置信息,主要是DefaultSpecificationSource类,关联一系列的NameSpace、IComponentSpecification、ILibrarySpecification这些类来查找当前应用所有的配置信息,从配置信息里查找service的定义。
?
其实默认的service就定义在Framework.library里面:
?
?
<service name="home" name="code">IPage home = cycle.getPage(IEngine.HOME_PAGE);cycle.activate(home);engine.renderResponse(cycle, output);
?
page是通过requestcycle来获取的,requestcycle正如其名,就是一次请求的一个流程,它保存着上下文requestcontext、engine等的引用,getpage方法就是将pagesource从engine中找出来,然后获取对应的ipage:
?
?
IPageSource pageSource = _engine.getPageSource(); result = pageSource.getPage(this, name, _monitor); result.setRequestCycle(this);
?
继续看会EngineService的service方法。
?
这里就是执行渲染页面的实际代码,首先获取到所要渲染的page。这个就从requestcycle中获取,然后activate这个page,其实就是执行校验调用page的validate方法。最后调用engine的渲染方法,最后会关联requestcycle、page去执行实际的渲染代码,迭代式的描述界面上的组件。
?
一个tapestry由请求,到engine,到找到对应的engineservice,初始化requestcontext、requestcycle,以及pagesource等,然后调用pageloader去创建ipage,然后进行描绘,然后将ipage缓存在Pool里面。大体上的流程就是这样。