struts2内幕读书笔记

Structs中的设计模式:

1、ThreadLocal模式:

为了解决多线程并发问题,jdk提供了一个类叫ThreadLocal。ThreadLocal在维护变量的时候,实际上使用了当前线程中的一个叫做ThreadLocalMap的独立副本,每个线程修改自己的副本而不会互相影响。

以下为java中ThreadLocal源码:

public class Thread implements Runnable{
ThreadLocal.ThreadLocalMap threadLocals = null;
}

public class ThreadLocal<T>{
public void set(T value){
Thread t = Thread.currentThread();
//获取当前线程的ThreadLocalMap
ThreadLocalMap map = getMap(t);
if(map!= null){
//如果不为空,设置当前的threadlocal为key
map.set(this,value);
}
else
createMap(t,value);
}
public T get(){
Thread t = Thread.currentThread();
ThreadLocalMap map getMap(t);
if(map!=null){
ThreadLocalMap.Entry e = map.getEntry(this);
if(e!=null){
return (T)e.value;
}
}
return setInitialValue();
}
ThreadLocalMap getMap(Thread t){
return t.threadLocals;
}
}

在传统的基于Servlet的开发模式中,Servlet对象内部的实例变量不是线程安全的。虽然同步机制是一种解决方法,但是效率太低,在Web中不可行。

在structs处理http请求和与XWorks框架交互之间使用了ThreadLocal模式。

在Spring中也用了ThreadLocal来管理Hibernate中的Session。

2、装饰模式:

其中HttpServletRequest、HttpServletRequestWrapper、HttpServletResponse、HttpServletResponseWrapper就运用了装饰模式。HttpServletRequestWrapper中具有传入HttpServletRequest的实例的构造函数,可以在继承HttpServletRequestWrapper接口的子类中对HttpServletRequest的具体方法进行补充。


HttpServletRequestWrapper就相当于Component,HttpServletRequest就相当于TargetComponent,而继承HttpServletRequestWrapper接口的子类就相当于ComponentDecrator。

3、策略模式:

XWork核心组件之一的容器中所管理的对象就是建立在“接口——实现”模式之下,而这也同时成为Struts2的插件实现的理论基础。

4、构造模式:

核心要素:
客户端角色:负责构造器的创建,对产品信息不知道
抽象构造器角色:这一组接口会由一个核心的build方法以及若干辅助方法共同构成。
具体构造器:封装了一个具体的产品对象,当build方法被调用时会实例化产品对象 并且返回,其中是通过一系列addfutures方法赋予对象属性。
产品角色:构造模式的产物。

5、责任链模式:

参与角色:
a.请求对象
b.执行对象的角色
责任链模式降低了请求的发送端和接收端的耦合。当一个事件的处理流程非常复杂而导致整个顺序执行的流程变得很长时,程序代码也会相应地变得难以维护。在这种情况下,我们非常有必要将一个顺序执行的流程步骤分派到不同的执行对象中去。

XWork框架中的拦截器栈就是基于责任链模式实现的。

XWork中的容器:

1、容器的引入:

如果程序中的对象创建过程以及获取依赖对象的过程靠程序自身逻辑来实现,那么有如下弊端:
对象将频繁创建,效率大大降低
对象的创建逻辑与业务逻辑代码高度耦合,舍得一个对象的逻辑关注度大大分散
程序的执行效率大大降低,由于无法区分明确的职责,很难针对对象实现的业务逻辑进行单元测试

所以我们应该引入一个与具体业务逻辑完全无关的额外的编程元素容器来帮助进行对象的生命周期管理。

2、容器管辖范围:

XWork容器所管理的对象包括所有框架配置定义中的“容器配置元素”。这些对象分为三类:
在bean节点中声明的框架内部对象
在bean节点中声明的自定义对象
在constant节点和Properties文件中声明的系统运行参数

3、对象的依赖注入:

步骤:
为某个对象的方法、构造函数、内部实例变量、方法参数变量加入@inject的Annotation
调用容器的inject方法,完成被加入Annotation的那些对象的依赖注入

struts2中数据沟通的桥梁——表达式引擎(OGNL):

1、数据流转的困境:

View层:
view层的数据模型将遵循http协议,因而它没有数据类型的概念,所有的数据在页面上的表现都是一个个扁平的、不带数据类型的字符串。
Controller层:
在Controller层,数据模型遵循Java的语法结构和数据结构,数据在传递时,将以对象的形式进行。
如果我们要数据在View层和Java世界中的互相流转传递,将会在“字符串”与“对象树”之间存在不匹配性,同一个对象,在“弱类型”的平台和一个“强类型”的平台之间交互,就必须有一个非常重要的“翻译”角色解决这种“不匹配”。这个角色就是表达式引擎,它充当这个桥梁的作用,保证数据能够顺利地在MVC的各个层次进行流转。

2、表达式引擎:

表达式引擎应该能处理表达式与对象之间的映射关系,这种映射关系应是双向的
表达式引擎应该能支持丰富多样的表达式语法计算
表达式引擎应该能够支持必要的数据类型转换

在Java世界中有许多优秀的表达式引擎,OGNL在内部实现机制和设计原理上有许多亮点,因而Struts2选择了OGNL作为其依赖的表达式引擎,并在OGNL基础上做了一定的扩展,使OGNL的应用更加丰富。

3、强大的OGNL:

OGNL是一个开源的表达式引擎,通过使用OGNL,我们能通过表达式存取Java对象树中的任意属性和调用Java对象树的方法等。也就是说,如果我们把表达式看成是一个带有语义的字符串,那么OGNL就是这个语义字符串与Java对象之间沟通的催化剂。

OGNL三要素:
a.表达式: 表达式说明了OGNL操作要干什么,表达式有固定语法规则,OGNL支持大量的表达式语法。
b.Root对象:
Root对象是指OGNL操作的对象是谁。
c.上下文环境:
上下文环境指OGNL操作的地方在哪里。它的数据结构是一个Map,称之为OgnlContext,之前所说的Root对象事实上也会被添加到上下文环境中,并且作为一个特殊的变量进行处理。对于上下文环境的访问,当访问其中某个参数的时候,需要通过#符号加上链式表达式来进行,从而表示与访问Root对象的区别。

XWork的设计原理

1、XWork微观视图

数据流元素
ActionContext——数据环境 无论是请求的参数,还是处理的返回值,甚至一些原生的Web容器对象,都封装于ActionContext内部,成为Struts2/XWork执行时所依赖的数据基础。
ValueStack——数据访问环境 ValueStack本身是一个数据结构,其主要作用是对OGNL计算进行扩展。因而,位于ActionContext之中的ValueStack则赋予了ActionContext进行数据计算的功能,从而使得ValueStack自身成为一个可以进行数据访问的环境。

控制流元素
ActionProxy和ActionInvocation在事件处理的过程中起到的作用主要是对事件处理节点进行调度执行,我们称之为事件处理驱动元素。

Action——核心处理类
Interceptor——拦截器 在Action执行之前和执行之后进行自定义的逻辑行为扩展。
Result——执行结果
XWork对Action执行完毕之后的相应处理动作。
ActionProxy——执行环境
ActionInvocation——核心调度器

Struts2初始化主线

其主要分为两个部分,一个是Dispatcher启动部分,第二个就是XWork启动,Dispatcher主要是负责与Web容器交互,获得http内容进行解析再封装,再传给XWork,使XWork可以做到与Web容器无关而注重MVC的实现。同时Dispatcher部分也需要读取配置文件,创建配置元素的一些工具类的实例,为XWork容器的初始化做准备。

正常一个http请求发送至服务器,服务器通常在内存中会实例化一个ActionServlet,这是一个单例,对于发送来的请求,服务器会查看http请求的是哪一个Action然后通过struts.xml查看对应的Action,如果在内存中存在,那么直接运行,否则通过创建线程的方式创建到相应的Action。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值