《Struts2技术内幕》 新书部分篇章连载(十)—— XWork概览

[b][size=x-large]第7章 别具匠心 —— XWork设计原理[/size][/b]

[b][size=large]7.3 XWork概览[/size][/b]

在了解了数据流和控制流的来龙去脉之后,我们再来看看XWork中实现这两大核心驱动力的编程元素以及它们之间的调用关系。相信有了之前所有的概念做铺垫,无论是XWork的宏观视图还是微观视图,读者理解起来应该可以驾轻就熟。

[b][size=large]7.3.1 XWork的宏观视图[/size][/b]

XWork的宏观构成示意图是XWork体系结构的核心,这个示意图我们曾经在第三章中向读者展示过,不过当时我们的引入此图的主要目的是为了说明XWork框架是Struts2的一个重要的组成部分,其具有非常丰富的内容。因而当时我们也并没有对其中的构成要素进行深入的分析。经过了之后各个章节的讲述,或许读者在这里会对这个示意图有一番更深刻的见解。整个示意图如图7-9所示:

[align=center][img]http://dl.iteye.com/upload/attachment/0062/4367/afb72477-8e29-30f0-aa92-97998a0477bf.png[/img][/align]

事实上,这张XWork的宏观示意图是整个XWork乃至整个Struts2的核心。此图内涵丰富,几乎涵盖了XWork的元素构成、XWork中元素的调用关系、XWork的执行层次以及XWork与外部调用接口之间的关系等所有XWork框架的核心内容。

在这里,我们将首先帮助读者理解这张示意图中的一些基本概念和基本的逻辑层次,在下一章中,我们将对示意图中的每一个元素进行详细的分析。

大家对于这张示意图的第一印象一定是这张图中不同类型的框框(有虚线的,也有实线的)。而这些不同的框框所围起来的构成要素,实际上代表着XWork框架中三个不同的体系结构:

[b]1. 核心分发器Dispatcher[/b]

[i]核心分发器Dispatcher位于整个示意图的最外层的Web容器中,它本身不属于XWork框架的组成部分。我们在这里把它纳入到XWork宏观示意图中,并作为一个重要的组成体系的主要原因在于它在Struts2中有着非常重要的低位。被称之为核心分发器的Dispatcher运行于Web容器中,却成为了XWork框架的调用者和驱动执行者。在图中,我们可以看到在核心分发器Dispatcher和下面的XWork元素之间有一条明显的虚线分割线作为它们之间的区分标志。
[/i]

[b]2. XWork的控制流体系[/b]

[i]XWork的控制流体系是指XWork进行请求响应的一系列执行元素,这一系列执行元素包括:ActionProxy、ActionInvocation、Interceptor、Action和Result。这些元素位于图中的下半部分,并被一个实线框封装于内部,由ActionProxy驱动执行。它们之所以被称之为XWork的控制流体系,是因为这些元素是真正的请求响应的逻辑处理载体,控制着整个请求响应的执行过程。[/i]

[b]3. XWork的数据流体系[/b]

[i]XWork的数据流体系是只XWork在进行请求响应时所依赖的一个数据环境,而这个数据环境中包含了两大元素:ActionContext和ValueStack。[b]这两大元素在图中所在的位置也比较特殊,它们都被虚线框包含其中。[/b]ActionContext所在的虚线框同时囊括了XWork控制流体系中的所有元素;而ValueStack所在的虚线框则囊括了核心控制元素的Action。这表明XWork的数据流元素在不同的控制流执行元素之间形成了[b]有层次的共享[/b],它虽然不直接参与控制流的执行体系,却是控制流执行过程中必不可少的核心依赖。[/i]

如果单单把重心放在XWork框架本身,我们可以发现XWork的体系结构正是按照控制流和数据流这两大核心驱动力进行划分的。结合核心分发器Dispatcher,我们可以归纳出这三大体系结构之间的层次关系:

[list]
[*][b]调用关系[/b]
[*][b]映衬关系[/b]
[/list]这里的“调用关系”,表明了XWork框架的空间范围,因为只有框架外的元素,才会对框架本身产生“调用关系”。因而我们可以发现核心分发器Dispatcher并不属于XWork框架的范畴,但是它却驱动着XWork框架的调用执行。

再来谈谈“映衬关系”。映衬关系则是一种非常微妙的关系。所谓“映衬”,实际上体现了一种“你中有我,我中有你”的水乳-交融的联系。XWork框架的控制流体系的执行基础是其数据流中的元素;而另外一个方面,失去了控制流的执行流程,数据流的所有元素也没有存在的意义了。

我们可以看到,“解耦合”这样一个开发中的最佳实践被XWork充分挖掘。XWork将数据流和控制流这两大驱动程序运行的基本力量进行物理隔离,将它们分派到不同的执行元素之上。但在运行期,两者又通过某种编程手段有机联系在了一起。这种看似很松,实际很紧的联系正是贯穿XWork框架总体设计的一个核心思想。

[b][size=large]7.3.2 XWork的微观视图[/size][/b]

当我们拥有了图7-9,实际上所有的XWork微观构成元素也通过示意图完全呈现在了读者的面前。对于所有这些微观元素的解读,也自然离不开对图7-9中元素和元素之间关系的解读。因而在这里,我们还是从XWork的数据流和控制流这两个截然不同的体系上,对XWork的微观构成给出一个大致的介绍。在下一章中,我们不仅将细化这些微观构成元素,还将具体展开这些微观元素之间的关系。

[b]7.3.2.1数据流元素[/b]

XWork的数据流体系,在图7-9中以虚线框的形式存在。我们可以在虚线框中看到构成数据流的两大元素:ActionContext和ValueStack:

[b]1. ActionContext —— 数据环境[/b]

[i]ActionContext是一个独立的数据结构,其主要作用是为XWork的执行提供数据环境。无论是请求的参数,还是处理的返回值,甚至一些原生的Web容器对象,都被封装于ActionContext的内部,成为了Struts2 / XWork执行时所依赖的数据基础。[/i]

[b]2. ValueStack —— 数据访问环境[/b]

[i]ValueStack本身是一个数据结构,其主要作用是用以对OGNL计算进行扩展。因而,位于ActionContext之中的ValueStack则赋予了ActionContext进行数据计算的功能,从而使得ValueStack自身成为了一个可以进行数据访问的环境。[/i]

在XWork对数据流的设计中,首要的考虑因素是功能性。根据之前我们对数据流的分析,构成数据流的元素,有两大基础的功能性要求:[b][color=red]数据存储和数据传输[/color][/b]。如果我们仔细分析ActionContext和ValueStack这两大元素,我们会发现ActionContext刚好是一个数据存储的容器,而ValueStack则接过了数据传输的责任大旗。这两大元素的相互配合,很好地诠释了数据流的完整过程。
那么,XWork对于数据流的设计有什么独到之处呢?

[quote="downpour"][b][color=red]结论[/color][/b] XWork对于数据流设计的亮点,在于数据流元素被设计成独立的数据结构。[/quote]

结合图7-6,我们可以看到数据流的主要构成:请求内容和响应内容。如果回顾一下传统的参数-返回值(Param-Return)模式和参数-参数(Param-Param)模式,我们会发现无论是请求内容还是响应内容,它们在表现形式上都作为方法(Method)的一个重要组成部分(要么作为方法的参数、要么就作为方法的返回值)。而[b]作为控制流主要载体的方法(Method)本身,对数据流元素形成了语法依赖。[/b]也就是说,在这种情况下,数据流和控制流之间是天然耦合的。因为作为控制流实现的主体方法,它与参数和返回值在语法层面被紧密联系在了一起。

而XWork采用了与控制流完全独立的对象实体来封装所有的数据流元素,并将控制流中的核心处理要素(Action)置于数据流之中,使两者形成水乳-交融的关系。这种设计的理念基于“解耦合”这样一个思想,使得原本无法分离的编程元素成为了形式上独立,运行上又紧密联系在一起的组件。这一点,正是XWork在数据流设计上的精华之处,也是读者需要细细品味的地方。

[b]7.3.2.2控制流元素[/b]

XWork的控制流体系,在图7-9中以实线框的形式存在。我们在实线框中可以看到构成控制流的元素主要有五个:ActionProxy、ActionInvocation、Interceptor、Action和Result。

这五大元素从功能逻辑上进行划分,还可以分成两类:其中的Interceptor、Action和Result被用于定义事件处理的基本流程,我们称之为事件处理节点;ActionProxy和ActionInvocation在事件处理的过程中起到的作用主要是对事件处理节点进行调度执行,我们将其称之为事件处理驱动元素。

我们在7.2.3章节中曾经深入分析过控制流的内部实现细节,并归纳了控制流的四大职责。不过当时我们并没有点出其中蕴含的一个XWork设计中的潜台词:

[quote="downpour"][b][color=red]结论[/color][/b] 结论:XWork认为,一个事件处理的流程是有规律并可以被继续细化的。[/quote]

正是基于这样一个基本观点,XWork建立起了一套定义事件处理流程的方法,并将它们映射到具体的Java对象中去。

[b]1. Action —— 核心处理类[/b]

[i]Action是XWork所定义的一个核心的事件处理接口。这个接口定义仅仅定义了一个没有参数的响应方法,从而使得所有实现Action接口的事件处理类,都自然而然地工作在属性-行为模式之上。其中,响应方法的内部完成对核心业务的处理,而事件处理类的内部属性则成为了响应方法进行业务处理的数据来源和响应结果。[/i]

[b]2. Interceptor —— 拦截器[/b]

[i]Interceptor本身是AOP的概念,表示对程序的某个逻辑执行点进行拦截,从而能够在这个逻辑执行点之前、之后或者环绕着这个逻辑执行点进行逻辑扩展。在XWork中,Interceptor的拦截对象是核心处理类Action,从而在Action的周围定义了一个环绕的逻辑扩展层次,其主要作用就在于能够在核心处理类Action的执行之前、之后进行自定义的逻辑行为扩展。[/i]

[b]Result —— 执行结果[/b]

[i]Result是XWork定义用以对核心处理类Action执行完毕之后的响应处理动作。Result被定义为一个独立的逻辑执行层次,其主要作用是使核心处理类Action能够更加关注其核心业务流程的处理,而将程序的跳转控制逻辑交给Result来完成。[/i]

通过Action、Interceptor和Result这三大元素的相互配合,一个完整的事件处理流程就可以被定义为:[b][color=red]以Action为业务处理核心,Interceptor进行逻辑辅助,Result进行响应逻辑跳转的具有丰富的执行层次的事件处理体系。[/color][/b]

如果回顾一下在7.2.3这一小节有关对控制流细节的描述,我们会发现三大元素的完整定义实际上完成了我们对事件处理流程进行规范化流程中的前两个步骤:[b]划分事件处理流程步骤和定义事件处理节点对象[/b]。而整个规范化流程中最为关键的步骤,也就是[b]组织事件处理节点对象的执行次序[/b],XWork则通过另外两个辅助对象来完成:

[b]1. ActionProxy —— 执行环境[/b]

[i]ActionProxy是整个XWork框架的执行入口。ActionProxy的存在,相当于定义了一个事件处理流程的执行范围,规定在ActionProxy内部的一切都属于XWork框架的管辖范围,而在ActionProxy之外,则只能以调用者的身份,与整个XWork的事件执行体系进行通讯。因此,ActionProxy的主要作用就在于对外屏蔽整个控制流核心元素的执行过程,对内则为Action、Interceptor、Result等事件处理节点对象提供了一个无干扰的执行环境。[/i]

[b]2. ActionInvocation —— 核心调度器[/b]

[i]ActionInvocation是组织起Action、Interceptor、Result等事件处理节点对象执行次序的核心调度器。ActionInvocation被封装于ActionProxy的内部,成为了XWork内部真正事件处理流程的总司令,它的执行调度过程,实际上控制着整个XWork事件处理体系的执行命脉。[/i]

在XWork的微观构成中,我们可以发现XWork的设计理念始终是将逻辑职责分派到最合适的编程元素之上。或许在这里我们还无法具体体会出XWork对这些具体元素的划分依据,不过我们已经可以从这些元素的名称中看出它们在框架中所处的不同地位。在下一章中,我们将对这些元素进行详细解读。

[b]【XWork控制流元素的一个形象比喻】[/b]

[i]XWork控制流被划分为五大元素:Action、Interceptor、Result、ActionProxy、ActionInvocation。我们可以使用一个战斗序列,来对这五大元素之间的关系进行诠释。
每当一个战役打响的时候,总指挥部总是需要分派一个具体番号的部队(ActionProxy)来执行战斗。任何一支部队,都有主力军(Action)和策应部队(Interceptor)。主力军(Action)负责核心战斗,而策应部队(Interceptor)则负责对主力部队进行策应和援助。然而,所有的战斗指令都是由部队的指挥官(ActionInvocation)决定的。指挥官(ActionInvocation)是一个部队(ActionProxy)的核心,他将负责主力部队(Action)和策应部队(Interceptor)的调度。当一个战斗结束以后,指挥官(ActionInvocation)还要负责指挥部队下一步的动向(Result),是乘胜追击敌人,还是继续待命。[/i]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
内容简介 出版日期: 2012年1月10日 《Struts2技术内幕:深入解析Struts2架构设计与实现原理》由国内极为资深的Struts2技术专家(网名:downpour)亲自执笔,iteye兼CSDN产品总监范凯(网名:robbin)以及51CTO等技术社区鼎力推荐。《Struts2技术内幕:深入解析Struts2架构设计与实现原理》以Struts2的源代码为依托,通过对Struts2的源代码的全面剖析深入探讨了Struts2的架构设计、实现原理、设计理念与设计哲学,对从宏观上和微观上去了解Struts2的技术内幕提供了大量真知灼见。同样重要的是,《Struts2技术内幕:深入解析Struts2架构设计与实现原理》还深入挖掘并分析了Struts2源代码实现中蕴含的大量值得称道的编程技巧和设计模式,这对开发者从Struts2的设计原理上去掌握和悟透Web层开发的要点和本质提供了绝佳的指导。 《Struts2技术内幕:深入解析Struts2架构设计与实现原理》主要分为3大部分,内容安排具有极强的逻辑推理性,章和章之间互相呼应且互为印证。知识准备篇首先介绍了获取、阅读和调试Struts2源代码的方法,以及Struts2源代码的组织形式;然后厘清了Web开发中极易混淆的一些重要概念,以及Struts2的核心技术、宏观视图、微观元素、配置元素等,提纲挈领地对Struts2进行了多角度的讲解。核心技术篇首先分析了Struts2中多种具有代表性的设计模式,然后对Struts2中的精华——OGNL表达式引擎和XWork框架的原理及机制进行了全面深入的分析和讲解。运行主线篇首先对Struts2的两大运行主线——初始化主线和HTTP请求处理主线进行了深入的剖析,然后对Struts2的扩展机制进行了解读和抽象。
Struts2技术内幕:深入解析Struts2架构设计与实现原理》由国内极为资深的Struts2技术专家(网名:downpour)亲自执笔,iteye兼CSDN产品总监范凯(网名:robbin)以及51CTO等技术社区鼎力推荐。   本书以Struts2的源代码为依托,通过对Struts2的源代码的全面剖析深入探讨了Struts2的架构设计、实现原理、设计理念与设计哲学,对从宏观上和微观上去了解Struts2的技术内幕提供了大量真知灼见。同样重要的是,本书还深入挖掘并分析了Struts2源代码实现中蕴含的大量值得称道的编程技巧和设计模式,这对开发者从Struts2的设计原理上去掌握和悟透Web层开发的要点和本质提供了绝佳的指导。   本书主要分为3大部分,内容安排具有极强的逻辑推理性,章和章之间互相呼应且互为印证。知识准备篇首先介绍了获取、阅读和调试Struts2源代码的方法,以及Struts2源代码的组织形式;然后厘清了Web开发中极易混淆的一些重要概念,以及Struts2的核心技术、宏观视图、微观元素、配置元素等,提纲挈领地对Struts2进行了多角度的讲解。核心技术篇首先分析了Struts2中多种具有代表性的设计模式,然后对Struts2中的精华——OGNL表达式引擎和XWork框架的原理及机制进行了全面深入的分析和讲解。运行主线篇首先对Struts2的两大运行主线——初始化主线和HTTP请求处理主线进行了深入的剖析,然后对Struts2的扩展机制进行了解读和抽象。
完整版:https://download.csdn.net/download/qq_27595745/89522468 【课程大纲】 1-1 什么是java 1-2 认识java语言 1-3 java平台的体系结构 1-4 java SE环境安装和配置 2-1 java程序简介 2-2 计算机中的程序 2-3 java程序 2-4 java类库组织结构和文档 2-5 java虚拟机简介 2-6 java的垃圾回收器 2-7 java上机练习 3-1 java语言基础入门 3-2 数据的分类 3-3 标识符、关键字和常量 3-4 运算符 3-5 表达式 3-6 顺序结构和选择结构 3-7 循环语句 3-8 跳转语句 3-9 MyEclipse工具介绍 3-10 java基础知识章节练习 4-1 一维数组 4-2 数组应用 4-3 多维数组 4-4 排序算法 4-5 增强for循环 4-6 数组和排序算法章节练习 5-0 抽象和封装 5-1 面向过程的设计思想 5-2 面向对象的设计思想 5-3 抽象 5-4 封装 5-5 属性 5-6 方法的定义 5-7 this关键字 5-8 javaBean 5-9 包 package 5-10 抽象和封装章节练习 6-0 继承和多态 6-1 继承 6-2 object类 6-3 多态 6-4 访问修饰符 6-5 static修饰符 6-6 final修饰符 6-7 abstract修饰符 6-8 接口 6-9 继承和多态 章节练习 7-1 面向对象的分析与设计简介 7-2 对象模型建立 7-3 类之间的关系 7-4 软件的可维护与复用设计原则 7-5 面向对象的设计与分析 章节练习 8-1 内部类与包装器 8-2 对象包装器 8-3 装箱和拆箱 8-4 练习题 9-1 常用类介绍 9-2 StringBuffer和String Builder类 9-3 Rintime类的使用 9-4 日期类简介 9-5 java程序国际化的实现 9-6 Random类和Math类 9-7 枚举 9-8 练习题 10-1 java异常处理 10-2 认识异常 10-3 使用try和catch捕获异常 10-4 使用throw和throws引发异常 10-5 finally关键字 10-6 getMessage和printStackTrace方法 10-7 异常分类 10-8 自定义异常类 10-9 练习题 11-1 Java集合框架和泛型机制 11-2 Collection接口 11-3 Set接口实现类 11-4 List接口实现类 11-5 Map接口 11-6 Collections类 11-7 泛型概述 11-8 练习题 12-1 多线程 12-2 线程的生命周期 12-3 线程的调度和优先级 12-4 线程的同步 12-5 集合类的同步问题 12-6 用Timer类调度任务 12-7 练习题 13-1 Java IO 13-2 Java IO原理 13-3 流类的结构 13-4 文件流 13-5 缓冲流 13-6 转换流 13-7 数据流 13-8 打印流 13-9 对象流 13-10 随机存取文件流 13-11 zip文件流 13-12 练习题 14-1 图形用户界面设计 14-2 事件处理机制 14-3 AWT常用组件 14-4 swing简介 14-5 可视化开发swing组件 14-6 声音的播放和处理 14-7 2D图形的绘制 14-8 练习题 15-1 反射 15-2 使用Java反射机制 15-3 反射与动态代理 15-4 练习题 16-1 Java标注 16-2 JDK内置的基本标注类型 16-3 自定义标注类型 16-4 对标注进行标注 16-5 利用反射获取标注信息 16-6 练习题 17-1 顶目实战1-单机版五子棋游戏 17-2 总体设计 17-3 代码实现 17-4 程序的运行与发布 17-5 手动生成可执行JAR文件 17-6 练习题 18-1 Java数据库编程 18-2 JDBC类和接口 18-3 JDBC操作SQL 18-4 JDBC基本示例 18-5 JDBC应用示例 18-6 练习题 19-1 。。。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值