9.2核心分发器 —— Dispatcher
9.2.1 核心分发器(Dispatcher)的核心驱动作用
Dispatcher之所以被称之为Struts2的核心分发器,主要是基于它在整个Struts2框架中的特殊地位。我们经常会使用“起-承-转-合”这4个不同的阶段来描述一个事件的整个过程,对于Struts2而言,Dispatcher实际上就是囊括这4个阶段的核心分发器。
9.2.1.1起 —— 负责系统初始化
Dispatcher在初始化时负责整个Struts2的初始化工作。在Dispatcher中,init()方法会在Dispatcher创建之初被调用,从而触发整个Struts2的初始化过程。所有的初始化方法在Dispatcher中都以init加上下划线作为起始进行命名,如图9-1所示:
从图中,我们可以看到init方法是一个public方法,是整个初始化过程中的操作窗口。而其余的所有以init加上下划线命名的方法,都将在init方法中以一定的顺序被依次调用。这些方法涵盖了在Dispatcher进行初始化过程中逻辑的方方面面。我们将在之后的源码分析中为读者详细解读。
9.2.1.2承 —— 接收并预处理Http请求
Dispatcher需要负责对Http请求进行预处理。这些预处理的过程主要包括:设置Encoding和Locale、对HttpServletRequest进行封装以及准备MVC运行的数据环境等。
这些预处理过程,由PrepareOperations在进行Http请求预处理的这个阶段调用执行。而我们知道PrepareOperations对象本身只是一个操作代理接口,真正完成逻辑功能的是Dispatcher本身。PrepareOperations在内部实现中所做的,只是对每个操作做了一个简单的转发处理。这些方法如图9-2所示:
注意在这其中的两个createContextMap方法,在这两个方法中,Dispatcher把Web容器相关的数据对象,封装成了普通的Java对象(实际上被封装成了Map对象)。这对于整个框架的意义不亚于任何其他任何的精妙设计。因为这两个方法的核心要义在于将Web请求数据进行“去容器化”处理,使得后续依赖于Web请求的任何操作,不再受限于任何的Web容器对象,从而真正做到了解耦合。读者可以结合在之前XWork章节中,我们对ActionContext初始化的相关描述,createContextMap方法实际上成为了ActionContext这个数据环境内部构造上下文环境的数据基础。
9.2.1.3转 —— 将Struts2转入XWork
在第三章中,我们提到Struts2在处理Http请求时还可以被分为2个阶段,而划分这2个阶段的临界点实际上就在于Dispatcher对象。
在第一个阶段中,所有的Http请求通过Dispatcher对象的Http请求的预处理,请求中与Web容器相关的对象全部被封装成与Web容器无关的对象,并构造出一个数据环境。于是,在第二个阶段中Dispatcher就能够将这一数据环境转发到XWork框架中执行,从而保证解耦在这一刻彻底完成。Dispatcher中进行请求转发的方法是serviceAction,如图9-3所示:
我们可以看到,serviceAction方法与Servlet规范中的service方法有着异曲同工之妙。只是在这里,serviceAction方法并不是Http请求处理的“终点”,反而是Struts2 / XWork中进行Http请求处理的“起点”和“中转站”。
serviceAction方法是整个Dispatcher对象的逻辑调度核心方法,也是整个Struts2在Http请求处理阶段的核心逻辑。我们将在下一章中对这个方法进行源码解读。
9.2.1.4合 —— 垃圾清理
Dispatcher不仅负责逻辑执行,还要负责在执行完毕之后进行对象清理。这一工作是由cleanup方法完成的,如图9-4所示:
在Dispatcher的cleanup方法中,将完成对Http请求的处理过程中产生的请求周期的对象的清理工作。我们在这里不再展开其源码的分析,不过我们可以将其源码中所涉及到的清理对象进行逻辑分类:
对于在整个请求周期中定义了完整的生命周期的框架元素的清理
例如,我们之前讲过的XWork中Interceptor对象,其接口定义中就蕴含了destroy方法。这个方法,就会在cleanup的流程中被调用执行。
对于线程安全的ThreadLocal对象的清理
我们知道,XWork中的ActionContext作为一个数据环境使用了ThreadLocal模式在整个当前线程共享数据,那么在整个请求结束时,与当前线程绑定的ActionContext的副本也在cleanup方法中被清理。
9.2.2 核心分发器(Dispatcher)的数据结构
Dispatcher中的内容如此丰富,以至于它成为了我们进行Struts2研究的最重要线索。之前我们已经看到了Dispatcher在不同阶段所承担的不同职责。接下来,我们从数据结构的角度来看看Dispatcher有什么独特之处。翻开Dispatcher的源码,我们可以看到Dispatcher内部的属性构成,源代码如代码清单9-3所示:
public class Dispatcher {
// 这里省略了许多其它代码
/**
* 提供了一个静态的ThreadLocal变量
*/
private static ThreadLocal<Dispatcher> instance = new ThreadLocal<Dispatcher>();
/**
* 提供一个接口方法,用于获取当前线程安全的dispatcher实例
*
* @return
*/
public static Dispatcher getInstance() {
return instance.get();
}
/**
* 将dispatcher实例绑定到当前线程
*
* @param instance
*/
public static void setInstance(Dispatcher instance) {
Dispatcher.instance.set(instance);
}
}
这个非常惹眼的内部变量instance,它不仅是一个静态的实例变量,同时它也被定义成为ThreadLocal类型,而ThreadLocal所承载的实际类型是Dispatcher本身!这正是一个典型的ThreadLocal模式的应用范例!
从这个数据结构的定义来看,我们可以确认,Struts2对Dispatcher应用了ThreadLocal模式。其中,Dispatcher本身就是实现ThreadLocal模式的核心要素,因为我们实际上在Dispatcher中看到了实现ThreadLocal模式的两大步骤。在之后的源码分析中,我们还将看到Dispatcher在处理Http请求时与ThreadLocal变量的交互过程。
使用ThreadLocal模式的初衷是为了解决多线程环境下对象访问的线程安全问题。Dispatcher作为核心分发器,成为了入口程序StrutsPrepareAndExecuteFilter中的实例变量PrepareOperations和ExecuteOperations的实际操作句柄(Dispatcher是它们的重要实例变量),从而被所有的线程共享访问。因此,Dispatcher被打造成ThreadLocal模式是一个理所当然的选择。
然而,这一理所当然的选择,却使得Struts2能够摆脱传统的表示层框架对于Web容器的高度依赖。由此可见,ThreadLocal模式是贯穿整个Struts2的核心技术之一,成为了Struts2将Web容器与Java开发解耦合的内在基础。不仅如此,我们还将在之后的章节中看到ThreadLocal模式在Struts2数据流转的过程中所起到的决定性作用。
最后,有两个针对Dispatcher重要结论需要强调一下:
downpour 写道
结论 Dispatcher作为一个线程安全的对象,涵盖了整个Struts2的生命周期。无论是Struts2的初始化,还是处理Http请求,实际都在Dispatcher中完成。
这个结论所针对的角度是Dispatcher的内容和职责,将它牢记于心,有助于日后我们对Struts2相关问题的调试和分析。实际上,对于Struts2的运行机理的一切研究,都离不开Dispatcher这个核心分发器。Dispatcher中所包含的所有方法,从一个侧面反应了Struts2框架的几个主要功能,而Dispatcher则处于一个“居中调度”的重要位置。
downpour 写道
结论 Dispatcher是Struts2与XWork的分界点,也是将MVC实现与Web容器隔离的分界点。
这个结论则从另外一个角度描述了Dispatcher在整个Struts2框架中的重要地位。它也成为了Struts2实现“解耦合”的核心所在。我们将在Struts2的第二条主线的分析中看到这个分界点以及它在框架中的逻辑意义。
- 大小: 10.1 KB
- 大小: 10.7 KB
- 大小: 2.6 KB
- 大小: 1.3 KB
分享到:
相关推荐
要深入学习和掌握Struts2,建议阅读官方文档,参与实际项目实践,也可以参考相关的技术书籍和教程,例如《Struts2技术内幕——深入解析Struts2架构设计与实现原理》等资源,来提升对Struts2框架的全面理解。
"Struts2 技术内幕——深入解析Struts2架构设计"这本书深入探讨了Struts2的核心机制和设计理念,帮助开发者更好地理解和应用这个框架。 Struts2的核心组件包括Action、Interceptor、Result和Configuration。Action...
《Struts2技术内幕:深入解析Struts2架构设计与实现原理》以Struts2的源代码为依托,通过对Struts2的源代码的全面剖析深入探讨了Struts2的架构设计、实现原理、设计理念与设计哲学,对从宏观上和微观上去了解Struts2...
《Struts2技术内幕:深入解析Struts2架构设计与实现原理》以Struts2的源代码为依托,通过对Struts2的源代码的全面剖析深入探讨了Struts2的架构设计、实现原理、设计理念与设计哲学,对从宏观上和微观上去了解Struts2...
总之,《Struts2技术内幕——深入解析Struts2架构设计与实现原理》配合《struts2基础.chm》,将帮助读者全面掌握Struts2的架构设计、核心组件、配置方式、插件使用以及源码解读,对于想要在Java Web领域深入发展的...
《Struts2技术内幕:深入解析Struts2架构设计与实现原理》由国内极为资深的Struts2技术专家(网名:downpour)亲自执笔,iteye兼CSDN产品总监范凯(网名:robbin)以及51CTO等技术社区鼎力推荐。 本书以Struts2的...
这本书《Struts2技术内幕——深入解析Struts2架构设计与实现原理》深入探讨了Struts2的核心机制和设计理念,旨在帮助开发者更好地理解和运用这个框架。 首先,Struts2的出现是为了解决Struts1在MVC模式中的局限性,...
本书以Struts2的源代码为依托,通过对Struts2的源代码的全面剖析深入探讨了Struts2的架构设计、实现原理、设计理念与设计哲学,对从宏观上和微观上去了解Struts2的技术内幕提供了大量真知灼见。同样重要的是,本书...
struts2技术内幕
《Struts2技术内幕:深入解析Struts2架构设计与实现原理》主要分为3大部分,内容安排具有极强的逻辑推理性,章和章之间互相呼应且互为印证。知识准备篇首先介绍了获取、阅读和调试Struts2源代码的方法,以及Struts2源...
《Struts2技术内幕 权威指南》是一本深入探讨Struts2框架的书籍,涵盖了该框架的核心概念、设计模式以及最佳实践。书中可能包含了以下几个关键知识点: 1. **Struts2架构**:Struts2的核心架构基于拦截器...
### Struts2技术内幕:深入解析Struts架构设计与实现原理 #### Struts2概述 Struts2是Apache Software Foundation支持的一个开源项目,它是Struts1的下一代版本,继承了Struits1的优点,并在此基础上进行了大量的...
这个“struts2——docs部分”很显然是Struts2官方文档或者相关的技术资料集合,通常包含详细的框架介绍、API参考、用户指南、教程等内容。在深入学习Struts2时,这些文档是非常重要的参考资料。 **1. 框架概述** ...
总结,Struts2作为Java web开发的主流框架之一,其核心技术包括Action、Interceptor、Value Stack、OGNL等,通过这些组件和机制,开发者能够高效地构建MVC应用,实现业务逻辑与表现层的分离,同时具备良好的扩展性...
资源名称:Struts2技术内幕:深入解析Struts架构设计与实现原理内容简介:本书由国内极为资深的Struts2技术专家(网名:downpour)亲自执笔,iteye兼CSDN产品总监范凯(网名:robbin)以及51CTO等技术社区鼎力推荐。...