struts2源码——XWork设计原理(一)

来源:互联网 发布:sql 外键 编辑:程序博客网 时间:2024/06/07 21:08

XWork是一个灵活而可靠的基于命令模式的开发框架。

1.请求—响应模式分析

(1)参数-返回值(Param-Return)模式

  • 方法签名 —— 请求-响应模式的处理载体
  • 方法参数 —— 请求内容映射
  • 方法返回值 —— 处理结果响应

对象的方法(Method)定义与我们之前对请求-响应模式的流程是相通的,从而使得对象的方法(Method)成为了请求-响应模式在Java世界中的一种直观抽象。

(2)参数-参数(Param-Param)模式
实际上比参数-返回值(Param-Return)模式更早出现。因为我们所熟知的Servlet标准就是基于参数-参数(Param-Param)模式进行设计的,因此这种参数-参数(Param-Param)模式也被称之为Servlet模式。

Servlet标准是j2ee的基本标准之一,在Servlet标准中定义的Http请求的处理接口如下图:

  • 参数列表 —— Http请求被封装为一个HttpServletRequest对象(或者ServletRequest对象),而Http响应封装为一个HttpServletResponse对象(或者ServletResponse对象)
  • 返回值 —— 方法不存在返回值(返回值为void)


因此,这里最大的不同就在于将返回值的位置转移到了参数列表之中。这种将请求和响应同时置于参数位置的模式,就是我们所说的参数-参数(Param-Param)模式。
从上一节的分析中,我们可以看到参数-返回值(Param-Return)模式是对Java语言对于方法(Method)这种编程元素的解读。那么为什么Servlet作为Java规范中进行Http响应的标准,却要采用参数-参数(Param-Param)模式来实现呢?

Servlet作为一个开发标准,它所设计的接口已经无法再将任何处理职责继续往上层推送了,因为它是我们进行Web开发的底层标准。因而对于Http请求的处理,我们在Servlet中不仅需要知道返回给请求的发起者(浏览器)一个什么样的处理结果,还需要真实地将处理结果呈现在浏览器中。而这一点,我们不得不借助HttpServletResponse对象的操作在doGet和doPost方法体的内部调用相应的接口函数来完成。因而此时,方法的“返回值”对于Servlet对象来说没有任何操作上的意义,Servlet必须通过HttpServletResponse的调用操作来完成浏览器的响应工作,这也就是我们不得不把HttpServletResponse置于参数位置的原因了。

由此可见,参数-参数(Param-Param)模式是一种最为基础的请求-响应实现机制,也是底层规范不得不采用的一种实现机制。这种实现机制虽然原始(因为它需要我们自行处理Http的实现细节),然而它却是实现完整请求-响应机制的唯一途径。

我们在绝大多数的Web开发框架中,并不会看到Servlet模式这种原始的实现模式,因为几乎所有的Web框架都会以这种模式为基础,将具体实现转化成另外两种实现模式。不过这种参数-参数(Param-Param)模式在形式上为我们带来的逻辑意义,依旧是值得我们深入思考的重要方面。

(3)POJO模式

pojo(Plain Old Java Objects)简单的Java对象)模式完全颠覆了前两种实现模式中以Java类中的方法的语法特性作为原型基础进行请求响应的传统模式。pojo模式实现请求-响应模式的代码构成示意图如下:

这就是POJO模式与前两种模式的最大区别:进行请求响应的处理类自身是否是一个有状态的对象。我们知道,传统的Servlet对象是一个无状态对象,也就是说它并不是一个线程安全的对象,我们不能在Servlet对象处理Http请求的过程中对Servlet对象内部的属性变量进行“安全”访问。这也就成为了Servlet对象处理Http请求无法逾越的一个障碍。从机制的角度讲,无论是参数-返回值(Param-Return)模式还是参数-参数(Param-Param)模式,它们都只是Servlet模式的有效变种。

而POJO模式则直接从概念上突破了Servlet对象的限制,将每一个请求的处理映射到一个线程安全的响应对象中去执行。因而从模式上讲,POJO模式是对传统的Servlet模式的一个重大改进,是一种崭新的请求-响应模式的实现。

不同的实现模式使用了不同的编程元素(方法参数、方法返回值、类的属性)来表达请求-响应模式中不同的逻辑语义。而产生这些分歧的本质原因,我们可以从主观和客观两个不同的角度来分析:

主观上 —— 不同的实现模式,它们考虑问题的出发点不同

这一点我们曾经在比较参数-参数(Param-Param)模式和参数-返回值(Param-Return)模式之间的区别时就提到过。前者作为一个底层的标准,不仅需要考虑到处理结果的返回(这可能是一个偏向于数据层面的响应结果),还需要考虑到后续的程序跳转(这就是偏向于控制层面的响应结果)。而后者,作为一个非底层的实现模式,则不需要考虑那么多的细节问题。

客观上 —— 不同的编程元素(方法参数、方法返回值、类的属性)所能够表达的逻辑功能存在着天然的差异

这一点则在面向对象语言的语法层面表现得比较突出。很显然,既然一个编程语言设计了多种多样的编程元素,那么它本来的意思一定是期望不同的编程元素能够表达出不同的逻辑含义和功能。

无论是哪种实现模式,都是在使用Java语言的语法元素来和整个请求-响应模式的过程中的元素进行配对。说得更加彻底一点,我们是在使用编程元素来对请求-响应的过程进行职责的划分。

那么,请求-响应模式的过程到底有哪些不可或缺的构成要素呢?我们还是使用一个示意图的形式来进行描述:

从图中,我们可以看到我们把整个请求-响应的过程划分为“请求”和“响应”这两个相反的过程,并分别继续根据其特点将整个过程划分为四个部分:

  • 请求内容 —— 请求的数据
  • 请求处理载体 —— 进行逻辑处理的场所
  • 响应内容 —— 逻辑处理的结果数据
  • 响应跳转处理 —— 逻辑处理完成后的程序流转方式


如果我们再把这上述的四个部分的内容和请求-响应的实现模式结合起来看,我们就能看到它们与Java语言中的编程元素的对应关系,如表所示: