上一章演示了如何运用第三方ORM工具来实现DAO中的具体数据库操作。选用的工具是当前最为流行的Hibernate。本章以更高层的企业级组件EJB来实现对应的功能。
8.1 J2EE架构概述
J2EE架构是当前Java Web应用中的主流应用架构,该架构包含大量高水准的企业级组件,是Java Web程序员必须在一定程度上了解和掌握的知识。
8.1.1 多层B/S结构与J2EE架构
1.B/S多层体系结构
长期以来,C/S(客户端/服务器)两层结构在软件开发中广泛应用,给人们带来相当的灵活性。但是,近年来网络应用的快速普及,以及业务处理要求的不断提高,C/S模式逐渐暴露出以下架构上的缺陷。
对客户端软件的维护问题。
网络传输数据的准确性和稳定性问题。
高负荷处理和平衡负载问题等。
随着网络应用技术的成熟,针对这一系列的问题,基于多层框架(三层或以上)的B/S(Browser/Server)结构应运而生。典型情况下,由表示层、业务逻辑层和数据层各自独立组成所谓的“三层架构”。其中,数据层又叫企业信息系统层、集成层或者持久化层,本书从技术角度采用持久化层的称谓。J2EE架构设想的分布式多层体系结构如图8-1所示。
该体系的核心是EJB组件,EJB是J2EE分布式应用的核心,但是一般的Web应用并不要求实现分布式应用,因此可以使用其他途径,如Hibernate、JDO等对象关系映射(ORM,Object—Relation Mapping)工具,或直接使用JDBC API实现数据持久化。

图8-1 J2EE多层分布式应用模型
在B/S多层体系结构中:
客户端只需符合要求的通用浏览器(比如某系统要求IE5.5以上版本),就可以使用所有服务,节省了客户端软件安装和维护成本,从而有效降低部署费用;
客户端(其实是表示层组件,这里只为和C/S模式对比理解)不再直接访问数据库,而通过中间业务逻辑层实现代理服务,从而可以方便地进行数据库和业务逻辑组件进化,各层次组件之间可以独立变化;
多层结构可以方便地管理外部资源,各组件之间通过服务接口互相协作,可以使用各种优化技术提高资源和服务的利用率,典型的应用是资源池优化技术;
错误和性能降低局部化,单独组件模块的错误和超载被最大限度的限制在本模块内部,维持整体服务的可用性。
当然,多层体系结构使系统层次结构复杂化,也在一定程度上造成了内部通信性能的降低和系统维护成本的上升。
2.J2EE持久层框架
目前,在Java Web应用中的主流框架是Sun的J2EE架构。本章在业务逻辑层一节中探讨了J2EE多层分布式应用模型。J2EE对持久层框架的实现提供了基本的实现架构,基本结构如图8-2所示。
可以看到,持久性框架是一组软件服务,将应用与其使用和操作的数据源分离,隐藏访问这些数据源的API。这些API组件包括JDBC、JDO以及实体Bean等。框架通过统一的DAO组件封装这些具体的访问逻辑。在各层次之间通过实现Serializable接口的可序列化对象(值对象或者数据传输对象等),传递对象化数据。
本书的主题Struts框架位于顶端的表示层,它接受用户的输入和操作,传递请求和数据给业务逻辑层,接收返回的结果呈现给用户界面。

图8-2 J2EE持久层框架
8.1.2 EJB组件简述
EJB(Enterprise JavaBean,企业级JavaBean)组件体系是J2EE框架的核心组件之一,最初被设计为支持分布式对象计算,因此在EJB2.0以前的版本中EJB组件只有远程接口,直到EJB2.0才因为实际应用的需求加入了本地接口。业界对EJB的评价主要源于其复杂程度,EJB并不是一个好学好用的组件。
使用EJB的正当理由:
Ø 提供应用层组件的集群;
Ø 提供与CORBA客户端的互操作;
Ø 消费JMS异步消息。
可以考虑使用EJB的理由:
Ø 提供多线程解决方案;
Ø 基于角色的访问权限控制;
Ø 熟悉EJB架构。
使用EJB的可疑理由:
Ø 清晰的多层体系结构;
Ø entity bean的O/R mapping能力;
Ø 基于RPC的分布式体系结构;
Ø 容器管理的基础设施(例如CMT)。
目前使用的EJB2.0规范包括3种EJB类型:实体Bean、会话Bean和消息驱动Bean。
1.实体Bean
实体Bean是J2EE核心的持久化组件,代表存储在外部介质中的持久化对象或者企业应用系统资源,它代表“实体”,必须实现javax.ejb.EntityBean接口。简单地说,实体Bean相当于数据库信息,但二者并不等价。因此可以理解为一个对象关系映射,不过这个对象关系映射身后有整个J2EE体系的支撑。
EJB2.0中,实体Bean分为BMP和CMP。
BMP是Bean—managed persistent entity
bean,中文就是Bean管理持久性实体Bean,它需要开发者自己编写符合EJB编程规范的实现代码,实现各种业务方法和管理方法,因此Bean-managed就是Bean接口自己编写代码实现持久性管理。
CMP是Container—managed persistent entity
bean,中文容器管理持久性实体Bean,顾名思义就是开发者不用再自己编写代码来实现持久性管理,借助集成开发工具甚至基本不用写代码,读者可以参考后面的例子。CMP是EJB2.0增加的类型,有效地降低了系统开发的复杂程度,但是在性能上比编写良好的BMP会稍有所下降。
2.会话Bean
会话Bean分为有状态会话Bean(Stateless Session Bean)和无状态会话Bean(Stateless Session Bean)两种,实现javax.ejb.SessionBean接口。在应用中被用来完成一些业务操作,因此它代表的是“动作”。不同的是,在有状态会话Bean中可以保存状态,而无状态会话Bean不能。因此,同一个无状态会话Bean的实例之间完全相同,只能用来执行通用操作。而有状态会话Bean的实例各自带有不同的属性值,可以用来维持客户会话,典型的应用是购物车。有状态会话Bean的作用在一定程度上类似JSP开发中常用的Session。
3.消息驱动Bean
消息驱动Bean(MDB,Message Driven Bean)是EJB2.0增加的类型,用来实现异步消息传递和处理机制,是实现JMS(Java Message Service,Java消息服务)的基础。JMS提供了一组标准的Java API实现消息传递和处理。消息传递和处理有两种方式:队列模型和机遇主题的发布/订阅机制。
队列模型是将消息对象放到消息队列中,监听该队列的消息驱动Bean取出消息进行处理,类似手机短信的形式(短信是消息对象,手机短信信箱是消息队列,机主是消息驱动Bean实例)。
发布/订阅机制则将消息分发给所有订阅者,类似生活中的报刊订阅。
本章主要演示如何使用实体Bean中的CMP来实现持久层。







