文章目录
  1. 配置元素与初始化主线
  2. 核心分发器:Dispatcher
  3. 配置元素的加载器:Provider
  4. 配置元素的构造器:Builder
  5. 配置元素的管理类:
  6. Struts2初始化主线详解
    1. 容器

struts2系列——初始化流程

配置元素与初始化主线

Struts2两大主线的入口程序是相同的,都是StrutsPrepareAndExecuteFilter,入口程序驱动了两条完全不同的主线运行。从init方法开始,主要针对三个元素展开的。

  • Dispatcher 核心分发器
  • PrepareOperations HTTP预处理类
  • ExecuteOperations HTTP处理执行类

初始化主线的核心驱动力是将各种形式的配置文件进行一次统一的对象化处理

核心分发器:Dispatcher

起:Dispatcher在初始化的时候负责整个Struts2初始化,init方法在Dispatcher创建之初被调用,从而触发整个struts2的初始化过程。

承:Dispatcher负责对Http请求进行预处理(包括设置Encoding和Locale。对HttpServletRequest进行封装以及准备MVC运行的数据环境),在这个过程中由PrepareOperations在Http请求预处理的阶段调用执行。其中两个createContextMap方法把web容器相关数据封装成了Java对象。这两个方法的核心在于将web请求进行“去容器化”使得后续依赖于web请求的任何操作不受限于web容器对象,做到了解耦合。

转:在http请求预处理之后(将http请求中与web容器对象相关的全部对象分装成与web容器无关对象封装成与web容器无关对象,构造出一个数据环境。在第二阶段中Dispatcher将这个环境发送到Xwork中。发送使用的方法是serviceAction。serviceAction是整个Dispatcher对象逻辑调度核心方法,也是在Struts2在HTTP请求处理阶段的核心逻辑。

合:调用cleanup方法清理http请求的处理过程中的请求周期的对象的清理工作。

Dispatcher涵盖了St2整个生命周期,st2的初始化和http请求都是在dispatcher中完成的。他也是st2余xwork的分界点,将MVC实现与web容器的分界点。

配置元素的加载器:Provider

配置元素的加载器是st2初始化主线的重要组成部分,st2定义了一个统一的配置加载器接口ConfigurationProvider。他多重继承了两个类ContainerPriovider和PackageProvider。前者是容器加载器,主要用于加载XML和Properties。实现原理是先进行init,然后调用register方法注册元素。

后者是事件映射加载器,在这个阶段中将XML配置文件中的package阶段全部内容被翻译成PackageConfig对象供St2使用

配置元素的构造器:Builder

容器构造器:ContainerBuilder

他是一个接口,他的作用是通过一定操作,将容器所需要管理的对象搜集起来,然后通过一个创建方法把容器创建起来。他满足了构造器的两个要求:

搜集参数:factory alice constant方法

构造对象:create方法

事件映射构造器:PackageConfig.Builder

配置元素的管理类:

配置管理元素:Configuration

配置操作接口:ConfigurationManager

初始化主线三大元素:

Dispatcher:初始化主线核心驱动力

Provider:初始化主线的操作载体

Builder:初始化主线中元素的构建方式

Struts2初始化主线详解

1

容器

面向对象的高级编程语言都是以对象为中心,对象之间的继承、嵌套引用关系所构成的对象树为我们进行对象级别的逻辑操作提供了足够的语法支持,但是对象之间复杂的关系也为对象生命周期带来了问题:

  • 在程序的运行期如何创建我们需要的对象?
  • 如何保证被创建出来的对象所关联的依赖关系(关联对象)也可以被正确创建出来?

在实现一个复杂的业务需求,离不开多个对象彼此协作共同完成。对象关系模型中协作的真正含义正式通过依赖对象的绑住,完成业务逻辑的过程。那么每个对象不得不依赖于其协作对象的引用和构建。那么每个对象对自己逻辑的执行能力是被他依赖的对象反向控制了,又称控制反转。

控制反转的提出对编程提出了:获取依赖对象 这一基本功能,如果这个功能通过程序逻辑自身实现,会存在很多弊端,于是容器(Container)被提出来了。所以容器是一个与业务逻辑完全无关的额外编程元素,来帮助对象生命周期管理。

这一编程元素(容器)需要遵循一定原则:

  • 容器应该被设计成全局、统一的编程元素
  • 在最大程度上降低容器对业务逻辑的入侵
  • 容器应该提供简单而全面的对象操作接口

结论:容器由一系列对象的操作接口构成,其中至少包含获取对象实例以及管理对象之间的依赖关系这两类操作方法。

进入init_preloadConfiguration(),在getConfiguration方法的调用中,我们不仅获得了Configuration对象的操作接口,也完成了对所有配置元素的调度。追进getConfiguration(ConfigurationManager.java),在这个方法中,调用了reloadContainer这个方法,我们继续追入。(DefaultConfiguration.java)这个方法是容器的初始化方法。

第0步:

this. packageContexts. clear(); this. loadedFi1eNames . clear(); vackaeeproviders - ArravList();

内部缓存对象的清理

第一步:

img

ContainerProperites可以追踪方法,可以看出,这是一个将Properties文件中的键值和ContainerBuilder关联起来的一个工具类。实际上ContainerBuilder收集参数的过程之一。

ContainerBuilder前面讲过,是container的构造器。

第二步:

Iterator i$ — providers . iterator(); while(i$. hasNext()) { Containerprovider containerprovider = (Container-provider) i$. next ( ) ; containerprovlder. init( configuration: this); containerprovider. register(builder, props); props . setConstants (builder); builder. factory (Configuration. class, create(context) { return DefaultConfü ActionContext oldContext ActionContext . getContext() ;

第二步是COntainerBuilder收集参数的过程。在containerProvider的register方法,本身就定义了containerBuild作为参数,因此在不同配置的加载方式实现类中,ContainerBuilder将会被调用。

第三步:

img

调用create把容器创建出来

第四步:

初始化时间映射关系。实际上就是对PackageProvider的生命周期调用过程。

第五步:

对PackageConfig初始化完成,对他的结构进行runtime改造,让她支持namespace的寻址方式。

支持一下
扫一扫,支持forsigner