SSH:Struts、Spring、Hibernate
SSH 框架指的是 Struts、Spring 和 Hibernate 三者的集成。集成 SSH 框架的系统从职责上分为表示层、业务逻辑层、数据持久层和域模块层。Struts 属于 MVC 框架的一种,提供了对 MVC 系统底层的支持,负责 MVC 的分离,在 Struts 框架的模型部分,控制业务跳转,利用 Hibernate 框架对持久层提供支持,Spring 则管理 Struts 和 Hibernate。
1.Struts
Struts 是一个基于 Sun J2EE 平台的 MVC 框架,主要是采用 Servlet 和 JSP 技术来实现的。由于 Struts 能充分满足应用开发的需求,简单易用,敏捷迅速,在过去颇受关注。Struts 把 Servlet、JSP、自定义标签和信息资源(message resources)整合到一个统一的框架中,开发人员利用其进行开发时不用再自己编码实现全套 MVC 模式,极大的节省了时间,所以说 Struts 是一个非常不错的应用框架。
官方地址:http://struts.apache.org
Struts2 在 Struts1 和 WebWork 的技术基础上进行了合并的全新的 Struts2 框架。其全新的 Struts2 的体系结构与 Struts1 的体系结构差别巨大。Struts2 以 WebWork 为核心,WebWork 的核心是 XWork。其优点如下:
- 实现了 MVC 模式,层次结构清晰,使程序员只需关注业务逻辑的实现。
- Struts2 提供丰富的拦截器实现。
- 强大的表达式语言(OGNL,the Object Graph Navigation Language)。
- 丰富的标签库,大大提高了开发的效率。
- 通过配置文件,就可以掌握整个系统各个部分之间的关系。
- 异常处理机制,只需在配置文件中配置异常的映射,即可对异常做相应的处理。
- Struts2 的可扩展性高。
- 面向切面编程的思想在 Struts2 中也有了很好的体现,最重要的体现就是拦截器的使用。
另外,Struts2 相对比于 SpringMVC,Struts2 对于 Controller 最大的改造有两点:
- 在 Controller 中彻底杜绝引入 HttpServletRequest 或者 HttpServletResponse 这样的原生 Servlet 对象。
- 将请求参数和响应数据都从响应方法中剥离到了 Controller 中的属性变量。
这两大改造被看作是框架的神来之笔。因为通过这一改造,整个 Controller 类彻底与 Web 容器解耦,可以方便地进行单元测试。
Suruts2 的工作原理可以用下面这张图来描述,下面我们分步骤介绍一下每一步的核心内容,需要说明的是,Struts2 在 2.1.3 版本之后,FilterDispatcher 核心控制器变成了 StrutsPrepareAndExecuteFilter。
这张图上分了好多块,彼此之间相互联系,先浏览一下各块的名字,再留心一下运行图最下面的图例,分为四种颜色。
- 橙色:Servlet Filters,过滤器链,所有的请求都要经过 Filter 链的处理。
- 浅蓝色:Struts Core,Struts2 的核心部分,Struts2 中已经做好的功能,在实际开发中不需要动它们。
- 浅绿色:Interceptors,Struts2 的拦截器。Struts2 提供了很多默认的拦截器,可以完成日常开发的绝大部分工作;当然,也可以自定义拦截器,用来实现具体业务需要的功能。
- 浅黄色:User Created,由开发人员创建的,包括 Struts.xml、Action、Template,是每个使用 Struts2 来进行开发的人员都必须会的。
架构图上有好多东西,接下来逐个击破。首先看看它们各自是做什么的,跟着图上的箭头一个一个来看:
FilterDispatcher
是整个 Struts2 的调度中心,根据 ActionMapper 的结果来决定是否处理请求,如果 ActionMapper 指出该 URL 应该被 Struts2 处理,那么它将会执行 Action 处理,并停止过滤器链上还没有执行的过滤器。ActionMapper
提供了 HTTP 请求与 Action 执行之间的映射,简单点说,ActionMapper 会判断这个请求是否应该被 Struts2 处理,如果需 Struts2 处理,ActionMapper 会返回一个对象来描述请求对应的 ActionInvocation 的信息。ActionProxy
是一个特别的中间层,位于 Action 和 xwork 之间,使得我们在将来有机会引入更多的实现方式,比如通过 WebService 来实现等。ConfigurationManager
是 xwork 配置的管理中心,通俗的讲,可以把它看做 struts.xml 这个配置文件在内存中的对应。struts.xml
是 Stuts2 的应用配置文件,负责诸如 URL 与 Action 之间映射的配置、以及执行后页面跳转的 Result 配置等。ActionInvocation
:真正调用并执行 Action,它拥有一个 Action 实例和这个 Action 所依赖的拦截器实例。ActionInvocation 会执行这些拦截器、Action 以及相应的 Result。Interceptor
:拦截器是一些无状态的类,拦截器可以自动拦截 Action,它们给开发者提供了在 Action 运行之前或 Result 运行之后来执行一些功能代码的机会。类似于我们熟悉的 javax.servlet.Filter。Action
:动作类是 Struts2 中的动作执行单元。用来处理用户请求,并封装业务所需要的数据。Result
:Result 就是不同视图类型的抽象封装模型,不同的视图类型会对应不同的 Result 实现,Struts2 中支持多种视图类型,比如 JSP,FreeMarker 等。Templates
:各种视图类型的页面模板,比如 JSP 就是一种模板页面技术。Tag Subsystem
:Struts2 的标签库,它抽象了三种不同的视图技术 JSP、Velocity、FreeMarker,可以在不同的视图技术中,几乎没有差别的使用这些标签。
一个请求在 Struts2 框架中的处理大概分为以下几个步骤:
- 户端初始化一个指向 Servlet 容器(例如 Tomcat)的请求。
- 这个请求经过一系列的过滤器(Filter),这些过滤器中有一个叫做 ActionContextCleanUp 的可选过滤器,这个过滤器对于 Struts2 和其他框架的集成很有帮助,例如:SiteMesh Plugin。
- 接着 FilterDispatcher 被调用,FilterDispatcher 询问 ActionMapper 来决定这个请求是否需要调用某个 Action,FilterDispatcher 是控制器的核心,就是 MVC 中控制层的核心。
- 如果 ActionMapper 决定需要调用某个 Action,FilterDispatcher 会把请求的处理交给 ActionProxy。
- ActionProxy 通过 Configuration Manager 询问框架的配置文件,找到需要调用的 Action 类。
- ActionProxy 创建一个 ActionInvocation 的实例。
- ActionInvocation 实例使用命名模式来调用,在调用 Action 的过程前后,会涉及到相关拦截器(Intercepter)的调用。
- 一旦 Action 执行完毕,ActionInvocation 负责根据 struts.xml 中的配置找到对应的返回结果。返回结果通常是一个需要被表示的 JSP 或者 FreeMarker 的模板。
- 将处理结果返回给客户端。
2.Spring
Spring 是一个解决了许多在 J2EE 开发中常见的问题的强大框架。 Spring 提供了管理业务对象的一致方法,并且鼓励注入对接口编程而不是对类编程的良好习惯。Spring 的架构基础是基于使用 JavaBean 属性的 Inversion of Control 容器。然而,这仅仅是完整图景中的一部分。
Spring 在使用 IOC 容器作为构建完关注所有架构层的完整解决方案方面是独一无二的。 Spring 提供了唯一的数据访问抽象,包括简单和有效率的 JDBC 框架,极大的改进了效率并且减少了可能的错误。Spring 的数据访问架构还集成了 Hibernate 和其他 O/R mapping 解决方案。Spring 还提供了唯一的事务管理抽象,它能够在各种底层事务管理技术,例如 JTA(Java Transaction API,Java 事务 API) 或者 JDBC 事务提供一个一致的编程模型。
Spring 提供了一个用标准 Java 语言编写的 AOP 框架,它给 POJOs 提供了声明式的事务管理和其他企业事务(如果你需要,还能实现你自己的 aspects)。这个框架足够强大,使得应用程序能够抛开 EJB 的复杂性,同时享受着和传统 EJB 相关的关键服务。Spring 还提供了可以和 IOC 容器集成的强大而灵活的 MVC Web 框架。
官方地址:http://www.springsource.org
后续会针对 Spring 详细讲解。
3.Hibernate
Hibernate 是一个开源的对象关系映射框架,它对 JDBC 进行了非常轻量级的对象封装,使得 Java 程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate 可以应用在任何使用 JDBC 的场合,既可以在 Java 的客户端程序实用,也可以在 Servlet/JSP 的 Web 应用中使用,最具意义的是,Hibernate 可以在应用 EJB 的 J2EE 架构中取代 CMP,完成数据持久化的重任。
官方地址:http://www.hibernate.org
为什么需要 Hibernate 呢?主要原因如下:
- 使用 JDBC 操作数据库时,SQL 语句都被编写在代码里面(硬编码),需要调整就得修改源码,灵活性差。每写一条操作都要创建一个 connection,这玩意儿十分消耗资源。对查询结果的解析、对参数的设置等,都与 SQL 语句有关,牵一发而动全身,耦合度极高。
- Hibernate 是一个 ORM(Object Relational Mapping,对象关系映射) 框架,所谓 ORM,即通过使用描述对象和数据库之间关系的元数据,将面向对象语言程序中的对象持久化到关系数据库中。说人话就是,通过一些简单配置,把 Java 类(一般是普通的 Bean)跟数据库表对应起来,这样就可以通过操作类来操作数据库。
- Hibernate 比较自动化,只要写个方法名就可以自动生成 SQL 语句,用起来贼拉方便。这里插一句,SSM 中的 MyBatis 跟 Hibernate 是对应的,两者最大的差别就是 MyBatis 并非自动生成 SQL,而是根据需要自行编写。一般来讲,手动挡比自动挡要省油,所以国内的许多公司对 MyBatis 情有独钟。(国外的开发者们似乎更喜欢 Hibernate)
Hibernate 框架执行过程:
- 通过 Configuration().configure() 读取并解析 hibernate.cfg.xml 配置文件。
- 由 hibernate.cfg.xml 中的 xxx.hbm.xml 读取并解析映射信息。
- 通过 config.buildSessionFactory():创建 SessionFactory。
- sessionFactory.openSession():打开 Session。
- session.beginTransaction():创建事务 Transaction。
- persistent operate:持久化操作。
- session.getTransaction().commit():提交事务。
- 关闭 Session。
- 关闭 SessionFactory。
4.整体架构
- Struts 负责 Web 层。
- ActionFormBean 接收网页中表单提交的数据,然后通过 Action 进行处理,再 Forward 到对应的网页,在
Struts-config.xml
中定义了 < < <action-mapping > > >,ActionServlet 会加戴进来。 - Spring 负责业务层管理,即 Service;
- Service 为 Action 提供统一的调用接口,封装持久层的 DAO,并集成 Hibernate,Spring 可对 JavaBean 和事物进行统一管理。
- Hibernate 负责持久层,完成数据库的 CRUD 操作:
- Hibernate 有一组
hbm.xml
文件和 PO,是与数据库中的表相对应的,然后定义 DAO,这些是与数据库打交道的类。
- Struts:用来控制的,核心控制器是 Controller。
- Spring:对 Struts 和 Hibernate 进行管理、整合的。
- Hiernate:操控数据库。
- Struts 标签库:Struts2 默认的表达式语言是 OGNL(Object-Graph Navigation Language),通过它可以存取对象的任意属性、调用对象的方法、遍历整个对象的结构图、实现字段类型转换等功能。
- JSP:HTML 文件中插入 Java 程序段和 JSP 标记。
web.xml
:Struts2 核心过滤器和监听器。struts.xml
:管理应用中的 Action 映射,及 Action 处理结果和物理资源之间的映射。applicationContext.xml
:整合了 Struts 和 Hibernate。*.hbm.xml
:O/R Mapping(Object Relational Mapping)映射文件,实体和表的映射关系通过 XML 来描述的文件。在项目启动的时候加载到内存中。- PO:Persistent Object,持久化对象。
- 整体的调用关系:JSP → Action → Service → DAO → PO → 数据库,也即 Struts → Spring → Hibernate。
系统的基本业务流程是: 在表示层中,首先通过 JSP 页面实现交互界面,负责接收请求(Request)和传送响应(Response),然后 Struts 根据配置文件(struts-config.xml)将 ActionServlet 接收到的 Request 委派给相应的 Action 处理。在业务层中,管理服务组件的Spring IOC 容器负责向 Action 提供业务模型(Model)组件和该组件的协作对象数据处理(DAO)组件完成业务逻辑,并提供事务处理、缓冲池等容器组件以提升系统性能和保证数据的完整性。而在持久层中,则依赖于 Hibernate 的对象化映射和数据库交互,处理 DAO 组件请求的数据,并返回处理结果。
SSH 框架优点:
- Spring 管理对象的实例化,把对象的创建和获取放到外部,更加的灵活方便。
- Hibernate 避免了 JDBC 连接数据库的冗余繁杂。
- 各层分工明细,实现了各层之间的解耦,代码更加灵活。