现在的位置: 首页 > 综合 > 正文

Tapesty系列之一 — 系统初启及请求处理

2013年12月13日 ⁄ 综合 ⁄ 共 4132字 ⁄ 字号 评论关闭

1.      系统启动

a)        说明:Tapestry启动时,采用的仍然是典型的HttpSerlvet的启动模式。在初始化的时候,他将加载用户定义的hivemodule.xml文件,并利用ApplicationInitializer存储整个Web应用的上下文,例如ServletContext等。在完成了上述初始化工作以后,将加载ServletRequestServicer,用于处理后续的http请求。

 

b)        流程图:

c)        代码:

                      i.              contructRegistry()

protected Registry constructRegistry(ServletConfig config){

String name = config.getServletName();

ServletContext context = config.getServletContext();

addModuleIfExists(builder, context, "/WEB-INF/" + name + "/hivemodule.xml");

addModuleIfExists(builder, context, "/WEB-INF/hivemodule.xml");

return builder.constructRegistry(Locale.getDefault());

}

 

注:上述代码主要完成的工作就是加载用户定义的hivemodule.xml文件。

 

2.      ApplicationInitializer

a)        说明:ApplicationInitializer采用的是Command模式,她主要负责加载Tapestry运行时的上下文。ApplicationInitializer的定义在tapestry.init.xml中。

 

b)        定义:

<contribution configuration-id="ApplicationInitializers">

<command id="WebContextInitializer" object="service:WebContextInitializer"

before="*"/>

<command id="ApplicationSpecificationInitializer"

object="service:ApplicationSpecificationInitializer"/>

</contribution>

 

c)        代码:

                      i.              WebContextInitializer.initialize()

public void initialize(HttpServlet servlet){

ServletContext servletContext = servlet.getServletContext();

WebContext context = new ServletWebContext(servletContext);

_globals.storeServletContext(servletContext);

_globals.storeWebContext(context);

}

 

注:上述代码主要是把ServeltContext等保存在Tapestry的全局注册表当中。

 

                   ii.              ApplicationSpecificationInitializer.initialize()

public void initialize(HttpServlet servlet){

IApplicationSpecification spec = null;

Resource specResource = findApplicationSpecification(servlet);

if (specResource == null){

spec = constructStandinSpecification(servlet);

}else

spec = _parser.parseApplicationSpecification(specResource);

_globals.storeActivator(new HttpServletWebActivator(servlet));

_globals.storeSpecification(spec);

}

 

注:上述代码主要是负责加载Tapestry.application文件。

 

 

3.      请求处理第一阶段

a)        说明:由于Tapestry采用的还是HttpServlet的模式,所以,他的入口仍然是继承自HttpServletApplicationServlet

ServletRequestServer内部,她主要完成的是把原有的HttpServletRequestHttpServletResponse进行封装,转换为Tapestry内部使用的WebRequestWebResponse,这样做的一个好处就是,使后续的代码不再依赖于底层所使用的HttpServlet,从而可以在一个完全的Tapestry框架内部进行操作。

WebRequestServicer内部,他所做的就是获取一个IEngine实例。而IEngine实例则是由EngineManager负责进行创建和维护,这里EngineManager提供了一个缓存,缓存基于Locale完成,也就是说对应于来自不同Locale的请求,EngineManager都将返回一个新的IEngine实例。当IEngine实例返回以后,后续的请求将由IEngine负责进行处理。

 

b)        流程图:

c)        代码:

                      i.              EngineManager. getEngineInstance()

public IEngine getEngineInstance(){

Locale locale = _localeManager.extractLocaleForCurrentRequest();

IEngine result = (IEngine) _enginePool.get(locale);

if (result == null)

result = _engineFactory.constructNewEngineInstance(locale);

return result;

}

 

注:上述代码用于返回基于LocaleIEngine实例。

 

4.      请求处理第二阶段

a)        说明:从IEngineservice()方法开始,我们转入了Tapestry的请求处理过程。在service()方法内部,IEngine通过RequestCycleFactorynewRequestCycle()方法创建一个IRequestCycle实例。

在创建IRequestCycle之前,RequestCycleFactory通过extractParameters()decodeParameters()来提取和分析URL当中的参数。其中decodeParameters()是使用ServiceEncoderdecode()方法进行提取。通过在hivemind.xml当中contribute不同的ServiceEncoder,我们可以参与整个URL参数的decode过程。这也是实现Perma Link的一般方法。

在参数解析和提取以后,Tapestry将根据之前的参数提取结果,获得当前应该使用的IEngineService,并调用其service()方法。Tapestry提供的IEngineService实现包括了DirectServicePageService等。

 

b)        流程图:

c)        代码:

                      i.              RequestCycleFactory. extractParameters()

private QueryParameterMap extractParameters(WebRequest request){

QueryParameterMap result = new QueryParameterMap();

Iterator i = request.getParameterNames().iterator();

while (i.hasNext()){

String name = (String) i.next();

String[] values = request.getParameterValues(name);

if (values.length == 1)

result.setParameterValue(name, values[0]);

else

result.setParameterValues(name, values);

}

return result;

}

 

注:上述代码用于从WebRequest当中提取参数,负责提取URL当中“?”后面的部分。

 

                   ii.              RequestCycleFactory.decodeParameters()

private void decodeParameters(String servletPath, String pathInfo, QueryParameterMap map){

ServiceEncodingImpl se = new ServiceEncodingImpl(servletPath, pathInfo, map);

for (int i = 0; i < _encoders.length; i++){

_encoders[i].decode(se);

if (se.isModified())

return;

}

}

 

注:这里利用ServiceEncoder来分析参数。

 

 

抱歉!评论已关闭.