XWork 容器原理(一)
次访问
XWork是Struts2运行机制的核心。
按照官方定义:XWork是一个灵活而可靠的基于命令模式的开发框架。所谓命令模式,本质上就是请求-响应模式。
请求响应的实现模式
参数-返回值模式
在这里,方法在语法上天然的能够与请求-响应模式相对应:
方法签名-请求-响应模式的处理载体
方法参数-请求内容映射
方法返回值-处理结果响应
SpringMVC就是基于这种模式来定义和实现 Http 请求的处理与响应的。
参数-参数模式
Servlet标准就是基于这种模式来进行设计的,因此这种模式也叫Servlet模式。
参数列表——Http请求被封装在一个HttpServletRequest对象,而响应被封装在HttpServletResponse对象中。
返回值——方法不存在返回值。
这种将请求和响应同时置于参数位置的模式,就是参数-参数模式。
为什么采用这种模式呢?
Servlet作为一个开发标准,它所设计的接口已经无法再将任何处理职责继续往上层推送了,因为它是Web开发最底层的标准。
POJO模式
在这种模式中,我们看到虽然实际进行请求的处理和响应的载体依然是POJO中的一个具体方法,但是我们并没有看到这个方法中存在任何参数。所有的请求参数,将以POJO内部属性变量的形式存在并被调用。所有的执行结果对象也同样以POJO内部属性变量的形式存在。这样一来,POJO相对应某一次的响应是一个有状态响应。因为响应处理流程、处理机制和处理结果,与当前POJO实例的内部属性的状态有关。
public class UserController {
private String username;
private String password;
public String login() {
return "success";
}
}
上面是一个普通POJO的例子。
可以看到,POJO模式与Servlet模式有很大不同,传统的Servlet对象是一个无状态的对象,即并非一个线程安全的对象,而POJO模式从概念上突破了Servlet对象的限制,将每一个请求的处理映射到一个线程安全的响应对象中去执行。
数据流和控制流
数据流和控制流是两股隐藏于程序内部的神秘力量,是程序运行的核心驱动力。
在整个请求-响应过程中,数据流实际上表现为数据内容,其核心包括数据请求和数据响应;而控制流实际上表现为方法进行逻辑处理的过程,包含程序的执行方向。
数据载体
在MVC中的Model层,我们对于数据的关注点主要有两个:数据存储和数据传输。Model所扮演的是一个载体角色。
载体必须有一定的数据结构,什么样的数据结构和数据形式最适合最为Web层的传输介质呢?
Map
基于键值对的数据结构。Servlet标准在设计HttpServletRequest规范时就是用了类似Map结构来进行数据交互。
在源码中这样定义方法:
public Map getParameterMap();//返回一个Map实例,以参数名称为键值,以参数实际值为Value的键值对。
public String[] getParameterValues(String name);
public String getParameter(String name);
这种方式的局限性:
1.Map的本质是一个容器结构,使用Map中的键值作为数据存取的依据,使得程序的可读性大大降低。
Map中的数据可以在任意情况下进行增删。当这些增删的逻辑散落在程序的各个角落时,我们很难在某一个特定时刻知道当前Map中到底有哪些Key值可以进行存取。
2.使用Map结构进行数据交互,无法实现必要的类型转化。
从上面的源码中可以看到,根据name可以取到页面上提交上来的值,但是那些值全部都是String或者String[]类型。Map无法提供Java所具备的强类型语言的基本功能。
FormBean
Struts1.X为代表的许多Web框架提出的数据交互载体的解决方案。
具体实现此处略去。大致问题是:某些方法实现需要框架和容器的支持,与框架耦合性太强。
POJO
1.作为JavaBean,POJO是一个具备语义的强类型。
2.POJO不依赖于任何框架,可以在程序的任何一个层次(如业务逻辑层或者持久层)复用。
3.POJO突破了FormBean对于页面元素唯一对应的限制,我们可以将一个页面的元素自由映射到多个POJO中去。
控制流的细节
控制层的核心职责是处理业务逻辑。
所以,控制层应该更加关注其核心的职责,而其他的辅助逻辑则由框架帮忙来完成。
XWork
XWork宏观视图
核心分发器
Dispatcher,本身不属于XWork的框架部分,但是它运行于Web容器中,是XWork框架的调用者和驱动执行者。
XWork 控制流体系
XWork进行请求响应的一系列执行元素:ActionProxy,ActionInvocation, Interceptor, Action, Result。
XWork 数据流体系
XWork在进行请求响应时所依赖的一个数据环境,包括两大元素:ActionContext 和 ValueStack。
XWork 微观视图
数据流元素
ActionContext: 是一个独立的数据结构,其主要作用是XWork的执行提供数据环境。无论是请求参数还是处理的返回值,甚至一些原生的Web容器对象都封装在ActionContext内部。
ValueStack:本身是一个数据结构,主要作用是对ognl 计算进行扩展。
XWork 构成数据流元素的两大基础性功能:数据存储和数据传输。由ActionContext负责数据存储,而ValueStack负责数据传输。
将数据流元素设计成为独立的数据结构,是XWork的一大亮点。传统的参数-返回值模式和参数-参数模式,无论是请求内容还是响应内容,在表现形式上都是方法的一个重要组成部分,作为控制流主要载体的方法本身对于数据流元素形成了语法依赖。造成了数据流和控制流天然耦合,参数和返回值在语法层面被紧密联系在一起。
控制流元素
从图中可以看到,构成控制流的元素有五个。从功能逻辑上划分可以分成两类:Interceptor/Action/Result被用于定义事件处理的基本流程,称之为事件处理节点;ActionProxy和ActionInvocation在事件处理的过程中起到作用的是对于事件处理节点进行调度执行,成为事件驱动元素。
下一篇博客将详细深入地介绍这七大元素。