Struts2的工作机制(转载)

struts2逻辑结构,此处引用自downpour文章 

downpour 写道

3.3.1.2 Struts2的初始化主线 

Struts2的初始化主线发生在Web应用程序启动之初,由入口程序的init方法驱动执行完成。这条运行主线主要特点有: 

仅在Web应用启动时执行一次 

由于这条主线由Filter中的init方法驱动执行,执行完毕后,该主线结束。也就是说,这条主线本身不参与后任何的Http请求的处理过程,无论Struts2之后再收到多少Http请求,这条主线都不会重复执行。 

Init方法的执行失败将导致整个Web应用启动失败 

如果在init方法执行的过程中发生异常,整个Web应用将无法启动。这个特点从框架规范的角度规定了我们必须确保初始化过程的顺利执行。因为在这个过程中,所以框架内部定义的元素将被初始化,并支撑起整个Struts2进行Http处理的过程。 

这两大特点本身其实来源于Filter这个Servlet规范的基本运行特性。然而,这两大特点却也为应用程序在框架的基础之上进行逻辑扩展提供了理论上的指导意见。在之后有关如何扩展框架的话题讨论中,我们可以看到所有的扩展方案都将基于这两大特点进行设计。 

那么,Struts2的初始化主线到底做了点什么呢?对应于Struts2初始化的运行特点,Struts2的初始化主线也有两大主要内容: 

框架元素的初始化工作 

这一初始化工作包含了对框架内部的许多内置对象的创建和缓存。我们发现,对于框架初始化工作的基本要求,就是在整个框架的运行过程中仅被执行一次,这正好符合这条主线的基本特点。 

控制框架运行的必要条件 

框架的可扩展特性保证了我们可以在应用层面对框架的运行参数和执行模式进行定制化,而框架则有必要对这种定制化进行正确性校验。当这种校验失败时,Web应用的启动会失败。这也就是Struts2在框架级别所能够提供的运行期的检查。 

初始化主线贯穿了Struts2对其内置对象的创建和缓存的过程,这一过程相当于把整个Struts2作为一个框架的运行环境完整地创建出来。这条主线的顺利运行,为之后的Http请求处理主线提供了必要的框架运行环境。 

我们在这里所说的运行环境和Struts2自身的运行环境不同,它是指建立在Web服务器之上,框架自身运行所必须的内置对象的集合。为了更好地对这些内置对象进行管理,Struts2引入了框架级别“容器”的概念。因而Struts2的初始化主线,实际上最终转化为对这个“容器”的初始化过程。有关这个“容器”的定义和初始化过程的细节,我们将在第五章中为读者解开谜团。 

3.3.1.3 Struts2的Http请求处理主线 

Struts2的Http请求处理主线是Struts2的核心主线,包含了Struts2处理Http请求、进行必要的数据处理和处理数据返回的全部过程。这条主线将在任何满足web.xml中所指定的URL Pattern的Http请求发生时进行响应,由doFilter方法负责驱动执行。 

如果我们回顾一下Struts2核心入口程序的流程图(图2-4),我们可以看到Struts2的Http请求处理主线又被一条分割线划分成了两个不同的执行阶段: 

第一阶段 —— Http请求预处理 

在这个阶段中,程序执行的控制权在Struts2手上。这个阶段的主要工作是针对每个Http请求进行预处理,为真正的业务逻辑执行做必要的数据环境和运行环境的准备。 
程序代码在这个阶段有一个非常显著的特点:依赖于Web容器,并时时刻刻将与Web容器打交道作为主要工作。 


第二阶段 —— XWork执行业务逻辑 

在这个阶段,程序执行的控制权被移交给了XWork。Struts2在完成了Http请求的预处理之后,将Http请求中的数据封装成为普通的Java对象,并由XWork负责执行具体的业务逻辑。 
程序代码在这个阶段的特点和第一阶段完全相反:不依赖于Web容器,完全由XWork框架驱动整个执行的过程。 

从Struts2对于Http请求的处理过程中,我们可以看出Struts2的核心设计理念在于解耦。所谓解耦,实际上是尽可能地消除核心程序对外部运行环境的依赖,从而保证核心程序能够更加专注于应用程序的逻辑本身。在Struts2中,我们所说的外部运行环境就是Web容器。我们在这里可以看到,Struts2的核心设计理念与Struts2的运行环境居然是一个矛盾体! 


老套路熟悉下Struts2框架和请求流程 

 
Struts2请求流程 
1、客户端发送请求 
2、StrutsPrepareAndExecute通过ActionMapper来决定这个Request需要调用哪个Action 
3、如果ActionMapper决定调用某个Action,FilterDispatcher把请求的处理交给ActionProxy,这儿已经转到它的Delegate--Dispatcher来执行 
4、ActionProxy根据ActionMapping和ConfigurationManager找到需要调用的Action类 
5、ActionProxy创建一个ActionInvocation的实例 
6、ActionInvocation调用真正的Action,当然这涉及到相关拦截器的调用 
7、Action执行完毕,ActionInvocation创建Result并返回,当然,如果要在返回之前做些什么,可以实现PreResultListener 

posted on 2015-03-02 10:59  hi_rain  阅读(341)  评论(0)    收藏  举报