《Struts2技术内幕:深入解析Struts架构设计与实现原理》读书心得

网上查阅开发框架资料时,知乎推荐《Struts2技术内幕:深入解析Struts架构设计与实现原理》这本书。本书2013年出版,在亚马逊上只有Kindle电子版,后来在孔夫子旧书网上下单买了一本旧的全新书。
购买本书时也犹豫过,一是,这是本号称技术内幕的书,担心作者会陷入技术的细枝末节;二是,对中国人写关于技术的书,大多在堆砌不同资料的套路中来回,结果都是大杂烩,对本质的东西反而讲不透。
但是当开始看这本书的时候,就真正被吸引了,有一种爱不释手的感觉。
作者的逻辑是,我们编程过程碰到什么问题?解决方案是什么样?具体实现方式以及背后的思想是什么?围绕这三个环节深入浅出的把Struts框架进行讲解,让人读后有一种醍醐灌顶的感觉,让读者真正做到知其然并知其所以然。
总体来说是一本难得的好书。
Struts2框架是表示层的框架,MVC又是表示层最经典的设计模式(最佳实践),所以本书最核心的部分是围绕着MVC模式在展开,讲述了为了满足MVC的实现,在数据流、控制流方面,整个框架是如何设计、各层是如何交互的。
虽然目前Spring MVC异军突起,已经有开始取代Struts2的局面,但是从框架原理和思想角度来说,其实是相通的。关键点不是具体技术的细节,而是技术后面的方法论,技术背后的思想和思考问题的方法。
下面是本书的一些读书笔记整理。

一、Struts2的架构






二、框架及设计模式

  • struts2
    是表示层框架的框架 因为其最为核心的内容就是和Web容器打交道,帮助我们处理Http请求。Struts2通过扩展实现Servlet标准来处理Http请求。
  • Spring
    是业务层的框架
  • Hibernate
    是持久层的框架

MVC是表示层的最佳实践(设计模式) M其实是请求--响应的数据模型(数据流)

本书的关于表示层的问题及解答表示层的困惑

三、容器及依赖注入

容器(Container),不仅支撑起一个框架的所有对象,同时也称为框架运行过程中最为重要的一个辅助元素,也是整个框架得以运行的核心基础。
为了更好的管理对象的生命周期,解决如下两个问题:

  • 1、在程序运行期间,应如何创建我们所需要的对象?
  • 2、当创建一个新的对象时,如何保证与这个对象所关联的依赖关系(其关联对象)也能够被正确的创建出来。

当我们需要寻求容器帮助时,只要再恰当的地方加入一个标识符Annotation,容器在进行依赖注入操作时,就能够知晓并接管整个过程了。在这里,我们看到两个过程共同构成了XWork容器进行对象依赖注入操作的步骤:

  • 1、没某个对象的方法、构造函数、内部实例变量、方法参数变量加入@Inject的Annotation;
  • 2、调用容器的inject方法,完成被加入Annotation的那些对象的依赖注入。

因为,我们这里顺利解决了容器定义中所提出的一个核心问题:如何建立起系统到容器或者容器托管对象的沟通桥梁--通过@Inject声明来完成。

在容器内部进行缓存的是对象实例的构建方法,而不是对象实例本身。这就让容器看起来像一个工厂集合,能够根据不同的要求,制造出不同种类的对象实例。

四、配置元素

配置元素分类:
从节点所表达的逻辑含义和节点在程序中所起的作用对配置元素进行分类。

  • 1、容器配置元素
    Bean节点:构成程序运行时的对象
    Constant节点:程序运行的执行参数
  • 2、事件映射关系
    Package节点:定义了一种事件请求响应的映射关系,反映的是Strut2对于外部事件情就是如何进行响应的处理序列。

五、Servlet及线程安全

是J2EEden重要标准之一,规定了Java如何响应Http请求的规范。通过httpServletRequest和HttpServletResponse对象,我们能够轻松地与Web容器交互。
线程安全,指的是在多线程环境下,一个类在执行某个方法时,对类的内部实例变量的访问时安全的。
Servlet兑现故事一个无状态的单例对象(singleton),所以可能这个实例在不同的线程执行的时候,导致线程的实例变量被修改,因而不是线程安全的。
ThreadLocal模式(以空间换时间)和Synchronized关键字(以时间换空间)都是用于处理多线程并发访问变量的问题。
ThreadLocal模式两个步骤:

  • 1、建立一个类,并在其中封装一个静态的ThreadLocal变量,使其成为一个共享数据环境;
  • 2、在类中实现访问静态Trespassing变量的静态方法(设值和取值)

使用ThreadLocal模式,可以对执行逻辑与执行数据进行有效地解耦。这一点是ThreadLocal模式给我们带来的最为核心的一个影响。因为在一般情况下,Java对象之间的写作关系,主要是通过参数和返回值进行消息传递,这也是对象协作之间的一个重要依赖。而ThreadLocal模式彻底打破了这种依赖关系,通过线程安全的共享对象来进行数据共享,可以有效避免在编程层次之间形成数据依赖。这也称为XWork事件处理体系核心的设计。

六、表达式引擎OGNL

表达式引擎 OGNL(Object Graph Navigation Language): 使用某些符合特定规则的字符串表达式来对Java的对象进行读和写的操作。 解决了Web应用与Java世界之间的沟通问题。既然要使用Java来开发Web应用,就必须使Java的变成要素能够与Web浏览器之间在数据层面保持良好的沟通,而这种沟通就是通过表达式引擎来完成的。
不同编程层次之间进行数据沟通的重要桥梁。
数据在不同的MVC层次上,扮演的角色和表现形式不同。这是由于Http协议与Java面向对象之间的不匹配造成的。如果我们要数据在View层(页面)和Java世界中互相流转传递,就会在“字符串”与“对象树”之间存在不匹配。这就需要一个翻译的角色来解决这种不匹配。这个角色,就是我们所说的表达式引擎。

七、请求 - 响应模式

  • 1、参数 - 返回值(Param-Return)模式
    对象的方法成为请求 - 响应模式在Java世界中的一种直观抽象;
  • 2、参数 - 参数(Param-Param)模式
    参数 - 参数模式是一种最为基础的请求 - 响应实现机制,也是底层规范不得不采用的一种实现机制。
  • 3、POJO模式
    POJO相对于某一次的响应是有状态响应。因为响应的处理流程、处理机制和处理结果,与当前POJO实例的内部属性的状态有关。
    POJO模式直接从概念上突破了Servlet的对象的限制,将每一个请求的处理映射到一个县城安全的响应对象中去执行。因而从模式上讲,POJO模式是对传统的Servlet模式的而一个重大改进,是一种崭新的请求 - 响应模式的实现。



文章摘录

  • 轻量级的Web应用服务器是Jetty,无需安装、速度快,成为众多程序员进行Web开发调试的首选。
  • 调试源码是本书最为推荐的一种源码级别学习方法
  • 因为只有了解了为什么,我们才能知道怎么做,知道如何才能做得更好。
  • 当我们加载一个JAR包到CLASSPATH时,实际上是获得了JAR中所有对JDK的额外支持。
  • 框架只是一个JAR包而已,其本质是对JDF的功能扩展
  • 最佳实践 Best Practice
    简单是美 Simple is Beauty!
    化繁入简 Heavy to light.
  • 可读性、可维护性和可扩展性。
  • 配置就像是程序的影子,与程序总是如影随形。
  • HTML语言是一种静态语言,它自身缺乏数据沟通的能力,也就是说,HTML语言需要另外一种机制的帮助才能完成与服务器端程序的沟通和逻辑控制。
  • JSP(Java Server Page)允许在构成Page的HTML语言之上,嵌入Java的语法片段,从而加强其与Server的交互能力。达到,页面视图的构建、与服务器端进行数据沟通。所有JSP在运行期间都被编译成Servlet在Web容器中运行。
  • HttpServletRequest兑现规划组要用于处理整个Http生命周期中的数据。
  • 视图的本质是Web容器对象HttpServletRequest(负责数据处理)和HttpServletResponse(负责内容呈现)对浏览器行为的控制。
  • AJAX技术所带来的对视图便是的最重要 影响谬事通过JavaScript操作HTML的DOM节点来进行视图输出控制。它也逐渐成为视图表现的一个重要选择方向。不过我们可以发现,使用JavaScript来进行视图输出的控制实际上是把视图呈现的职责转移到了客户端变成的范畴,这是一种“职责转移”。
  • 模块化实际上只一种“分而治之”的思想。