1 SSH在开发中的位置

现在J2EE的开源框架多的数不清楚,目前(已经、正在)比较流行的常用框架大概有struts,spring,hibernate,jsf,webwork,而 struts+spring+hibernate(SSH)这种轻量级架构被誉为“黄金组合”。spring和hibernate更是被许多人认为是未来五年内不会被淘汰的技术,犹如当年的struts,今天的开发中依然被广泛采用。

2 为什么使用SSH  

其实,就算用Java建造一个不是很烦琐的web应用,也不是件轻松的事情。 在构架的一开始就有很多事情要考虑。从高处看,摆在开发者面前有很多问题:要考虑是怎样建立用户接口?在哪里处理业务逻辑? 怎样持久化的数据。 而这三层构架中,每一层都有他们要仔细考虑的。 各个层该使用什么技术?怎样的设计能松散耦合还能灵活改变? 怎样替换某个层而不影响整体构架?应用程序如何做各种级别的业务处理(比如事务处理)?

    构架一个Web应用需要弄明白好多问题。 幸运的是,已经有不少开发者已经遇到过这类问题,并且建立了处理这类问题的框架。 一个好框架具备以下几点:减轻开发者处理复杂的问题的负担("不重复发明轮子");内部有良好的扩展; 并且有一个支持它的强大的用户团体。 好的构架一般有针对性的处理某一类问题,并且能将它做好(Do One Thing well)。 然而,你的程序中有几个层可能需要使用特定的框架,已经完成的UI(用户接口) 并不代表你也可以把你的业务逻辑和持久逻辑偶合到你的UI部分。 举个例子,你不该在一个Controller(控制器)里面写JDBC代码作为你的业务逻辑, 这不是控制器应该提供的。 一个UI 控制器应该委派给其它给在UI范围之外的轻量级组件。 好的框架应该能指导代码如何分布。 更重要的是,框架能把开发者从编码中解放出来,使他们能专心于应用程序的逻辑(这对客户来说很重要)。 

他们里面有很我优秀的设计理念及模式应用。比如, struts属于MVC框架,关键是要了解MVC的概念及大致原理,掌握就很容易了;而hibernate属于orm系统,属于持久层的解决方案,同样需要对ORM的概念及原理有一个总体的了解,必要时可以去查查EJB1及EJB2里面用于持久层的Entity Bean的使用。而spring属于应用程序框架,其核心是IOC容器以及AOP,把这两个核心概念(也可称为大模式)了解以后,再加上一定的内力修为,其它就都不难了。Spring中还集成了很多适用东西(不过这些东西80%的在某一个项目中可能一直用不上),比如对JDBC的封装、自己的MVC、对动态语言的简洁访问等,这些你根据自己的项目情况来选择学习,用到的时候再看看他的文档,一个项目下来应该就能把握。

3 对于SSH的理解

在SSH框架中,struts用来解决MVC中显示、请求控制部分,spring主要负责访问数据库DAO类的事务控制以及它被人称誉的IOC思想在业务类中的恰当运用,hibernate主要是充当数据访问层组件。由于spring对hibernate的良好支持,在DAO类主要由spring来完成,hibernate更多关注的应是O/R影射文件上的配置,如级联关系,延迟加载等如何设置才能使效率更高。见图1 (框架组合示意图)

4 收获和问题

4.1 actionform,PO,VO三对象的运用

讨论最多的是actionform,PO,VO三对象的运用,本人倾向的观点是:在SSH框架中,PO和VO可以不必区分,即业务层和持久层都可以使用hibernate产生的PO对象,我暂时把对象分成actionform和po两种来分析,action 应该是actionform和po的分界点,po不能穿透业务层,突破action到达页面显示层,同样actionform也不能突破action传到后台业务、持久层。(原因:po是持久对象,到达页面后就脱离了session成为无状态(暂理解为脱管态)的对象,而hibernate的持久对象是有状态(包含数据库主键)的,无状态的对象传到后台在调用hibernate的保存方法时会出错,一定要把无状态的对象先转化成持久态对象才能保存)在action中应该对两对象进行转化,转化的方法目前我还没发现有什么非常好的方法(欢迎高手不惜赐教),最普通的就是用get(),set()方法,也可以使用struts提供的属性复制方法BeanUtils类,但这个好象只支持单个类的转化,对于集合对象不行,需要我们自己扩展。

4.2 spring事务管理

在配置spring的事务管理中,最好把事务控制配置在业务类上,而不要配置在DAO类(需要保证多个原子事务操作同时失败回滚时这是一种解决办法);

4.3 action如何获取业务类

action中如何获取业务类:写一个父类action,在父类中通过spring的webapplicationcontent获得业务类的实例。struts中的具体action继承该父类,通过调用父类的getService()直接获得业务类的实例。

4.4 理解AOP思想

深入理解AOP思想,我暂时感觉到的就是尽量面向接口编程,不管是域对象还是业务类或者是DAO类都设计出接口,在各方法中我们尽量传入对象的接口,这对我们重用这些方法,扩展是很有好处的。

4.5 分页处理 level

5 系统包划分

这是一个真实项目的例子:

系统包划分

包名

描述

com.projectname.domain

逻辑调用信息的载体Bean和hibernate的配置

com.projectname.lgc

逻辑层服务封装的接口或抽象类

com.projectname.dao

数据库访问的抽象类

com.projectname.dao.impl

数据库操作的具体实现

com.projectname.web.action

控制页面跳转或Servlet

com.projectname.common

系统通用