第3课 EJB快速入门

EJB(Enterprise JavaBean)是Java EE的一部分,它是Java EE分布式开发中的框架技术。它定义了Java服务器端服务框架的规范,用以描述一些必需的服务,如事务、安全和名字服务等。因此,EJB提供了分布式企业开发的基础框架,在这个框架中,开发人员可以进行各种业务的开发、部署和访问。

本课作为EJB企业开发技术的第一课,我们首先需要了解EJB,并构建起EJB 3运行服务器环境和开发环境,并在该环境下开发第一个HelloWorld应用实例。主要内容如下。

● 开始了解EJB:了解EJB的基本概念、特性、体系结构、组件类型、发展历史等,对EJB有一个全面整体的了解,为后文的分块讲解做好准备。

● 配置EJB运行环境——JBoss服务器:选择JBoss作为EJB运行的服务器,并下载和安装JBoss,测试该环境的可用性,为EJB程序的部署做好准备。

● 配置EJB集成开发环境——Eclipse+JBoss Tools插件:在Eclipse中安装JBoss Tools插件,并在该集成环境下新建JBoss服务器,启动和测试可用性。

● EJB快速上手——HelloWorld入门实例:在Eclipse中开发一个Session Bean组件,实现返回欢迎信息的功能,并自动发布部署到JBoss服务器中,然后编写Java类或JSP页面实现对EJB服务的访问。

本课的内容如图3-1所示,左侧方框内构建的是Eclipse+JBoss+JBoss Tools的运行环境和集成开发环境,左侧上方是基于该环境开发并部署的HelloWorld服务端,它通过JNDI暴露服务的地址,可以被Java、JSP和Servlet等客户端程序所访问。

图3-1 内容结构图

通过本节课的学习,你将能够搭建起EJB运行和开发的环境,并能够熟练掌握EJB程序的开发、部署和访问的全过程。

3.1 开始了解EJB

首先我们从以下几个方面来了解EJB。

● EJB基本概念:EJB、EJB容器和EJB服务器。

● EJB基本特性。

● EJB体系结构。

● EJB组件的3种类型:会话Bean、实体Bean、消息驱动Bean。

● EJB发展历史:EJB 1.0、EJB 1.1、EJB 2.0、EJB 2.1、EJB 3.0。

● EJB 3.0新特性。

3.1.1 EJB基本概念

EJB(Enterprise JavaBean)是Java EE的一部分,定义了一个用于开发基于组件的企业多重应用程序的标准。其特点包括网络服务支持和核心开发工具(SDK)。从技术上来说,EJB不是一种产品,而是Sun在Java EE中指定的一套规范,该规范规定了一系列的API,用来实现把EJB概念转换成EJB产品。

在开始研究EJB之前,我们先来了解EJB中的几个基本概念: EJB、EJB容器及EJB服务器。

1.EJB

在Java EE里,Enterprise JavaBean称为企业JavaBean,即它是企业级的JavaBean组件。Enterprise JavaBean和JavaBean都是Java的组件模型,但是Enterprise JavaBean组件模型和JavaBean组件模型有本质的不同:

● JavaBean规范定义了事件和属性等特征,其重点是允许开发者在开发工具中可视化地操纵组件。JavaBean规范详细地解释了组件间事件登记、传递、识别和属性使用、定制和持久化的应用编程接口和语意。

● Enterprise JavaBean规范详细地定义了一个可以移植性地部署Java组件的服务框架模型。其中并没提及事件,因为Enterprise JavaBean通常不发送和接受事件。同样它也没有提及属性——属性定制并不是在开发时进行的,而是在运行时(实际上是在部署时)通过一个部署描述符来描述的。

它们二者都是组件模型规范,但是前者说明了开发工具中应用程序组装的问题,而后者则侧重于部署组件的服务框架的细节。区别是当你使用JavaBean创建服务器应用时,你还得设计整个的服务框架,而Enterprise JavaBean框架则是现成的,你只需遵守它的API即可。对于复杂的服务器端应用程序,显然使用Enterprise JavaBean比重新开发更简单。

注意

不要错误地认为JavaBean用于客户端的开发,Enterprise JavaBean用于服务器端的开发。

2.EJB容器

EJB类的对象驻留在EJB容器内,EJB容器是向开发者提供各类服务的环境。容器根据具体的配置可以负责处理安全、事务和实例管理。由于开发人员无须再亲自完成这些任务,因此大大节约了开发时间。

J2EE服务器和EJB容器这两个概念之间存在显著差别,EJB容器可能属于J2EE服务器的一部分,但却并不一定是必需的组成部分。在作为J2EE服务器组成部分的情况下,EJB客户程序通常会采取Servlet或者JSP的形式。不过,由于取消了对J2EE Web层的依附性,标准的EJB容器服务可以接受多种类型的客户程序、用Java或其他各种语言编写的应用程序所发出的请求。同EJB容器的通信才是客户操作的先决条件。

3.EJB服务器

EJB容器是管理一个或多个EJB类/实例的抽象,它通过规范中定义的接口使EJB类访问所需的服务。容器由EJB服务器来提供,一旦接口标准化了,厂商就可能提供可以在任何兼容的EJB服务器上运行的容器。

EJB服务器是管理EJB容器的高端进程或应用程序,并提供对系统服务的访问。EJB服务器也可以提供厂商自己的特性,如优化的数据库访问接口,对其他服务(如CORBA服务)的访问,对SSL 3.0的支持等。一个EJB服务器必须提供对可访问JNDI的名字服务和事务服务的支持。一些可能的EJB服务器的例子如下:

● 数据库服务器。

● 应用服务器。

● 中间件服务器。

容器厂商也可以在容器或服务器中提供额外服务的接口。

3.1.2 EJB基本特性

EJB是专门为服务器端组件市场制定的规范。EJB是一种让开发者快速开发大规模企业应用的组件体系结构,它让应用开发者在不花费任何代价的前提下,为中间件提供复杂的企业级特性。通过应用EJB,你可以全身心地投入到解决实际问题的应用软件的开发中,而不用花费精力处理分布式服务器端系统所带来的底层问题。你可以放心地将EJB认为是大多数企业级应用所需的通用功能组件。EJB模型可以让你避免这些底层功能的重复开发,从而提高效率。

EJB是Sun的服务器端组件模型,最大的用处是部署分布式应用程序。它具有以下特性:

● EJB增加了与其他系统相兼容的灵活性。对于现有的应用系统,不需要从头开发企业级的应用系统,在不废弃现有的企业级应用系统的前提下,将系统升级到EJB模式。

● EJB还支持“即插即用”的企业级特性。EJB这个中间件构造了可扩展的多层体系结构,应用服务器潜在地为运行在其中的组件提供事务处理、连续性、安全、组件生存期管理、线程等服务。

● EJB是跨平台和跨厂商的。这就出现了一个可以综合所有厂家产品的通用分布式组件体系结构标准,EJB市场竞争的激烈可以使开发商将注意力集中在最好的应用的开发上。

3.1.3 EJB体系结构

EJB分布式应用程序是基于对象组件模型的,底层的事务服务用了API技术。EJB技术简化了用Java语言编写的企业应用系统的开发和配置。EJB技术定义了一组可重用的组件:Enterprise JavaBean。你可以利用这些组件,像搭积木一样地建立你的分布式应用程序。当你把代码写好之后,这些组件就会被组合到特定的文件中去。每个文件有一个或多个Enterprise JavaBean,再加上一些配置参数,最后,这些Enterprise JavaBean被配置到一个装了EJB容器的平台上。客户能够通过这些Bean的home接口,定位到某个Bean,并产生这个Bean的一个实例。这样,客户就能够调用Bean的应用方法和远程接口了。

(1)EJB服务器作为容器和底层平台的桥梁管理着EJB容器和函数。它向EJB容器提供了访问系统服务的能力。例如数据库的管理和事务的管理,或者对于其他的Enterprise的应用服务器。所有的EJB实例都运行在EJB容器中。

(2)EJB容器提供了系统级的服务,控制了EJB的生命周期。EJB中有一些易于使用的管理工具,内容如下。

● 安全(Security):配置描述器定义了客户能够访问的不同的应用函数。容器通过只允许授权的客户访问这些函数来达到这个效果。

● 远程链接(Remote Connectivity):容器为远程链接管理着底层的通信issues,而且对Enterprise JavaBean的开发者和客户都隐藏了通信细节。EJB的开发者在编写应用方法的时候,就像是在调用本地的平台一样。客户也不清楚他们调用的方法可能是在远程被处理的。

● 生命周期管理(Life Cycle Management):客户简单地创建一个Enterprise JavaBean的实例,并通常取消一个实例。而容器管理着Enterprise JavaBean的实例,使Enterprise JavaBean实现最大的效能和内存利用率。容器能够这样来激活和使Enterprise JavaBean失效,保持众多客户共享的实例池。

● 事务管理(Transaction Management):配置描述器定义了Enterprise JavaBean的事务处理的需求。容器管理着那些管理分布式事务处理的复杂的issues,这些事务可能要在不同的平台之间更新数据库。容器使这些事务之间互相独立,互不干扰,并保证所有的更新数据库都是成功发生的,否则就回滚到事务处理之前的状态。

(3)EJB组件是基于分布式事务处理的企业级应用程序的组件。所有的EJB都有如下的特点:

● EJB包含了处理企业数据的应用逻辑。

● 定义了EJB的客户界面。这样的界面不受容器和服务器的影响。于是,当一个EJB被集合到一个应用程序中去时,不用更改代码和重新编译。

EJB能够被定制为各种系统级的服务,例如安全和事务处理的特性,都不是属于EJB类的,而是由配置和组装应用程序的工具来实现的。

3.1.4 EJB组件的3种类型

EJB组件对象分为3种类型:Session Bean、Entity Bean、Message Driven Bean。根据所需要的Bean行为,决定所采用的Bean类型。下面来看各种类型的作用和使用场景。

1.Session Bean——会话Bean

Session Bean用于实现业务逻辑,它可以是有状态的,也可以是无状态的。每当客户端请求时,容器就会选择一个Session Bean来为客户端服务。Session Bean可以直接访问数据库,但更多时候,它会通过Entity Bean来实现数据访问。

会话Bean还可以进一步细分为无状态会话Bean和有状态会话Bean。

1)无状态会话Bean

无状态会话Bean并不知道客户或者涉及请求的上下文,从而使其成为单一请求/回应应用的理想工具。比如,一个用户在Google中搜索关键字“Java”,客户应用程序联系一个无状态会话Bean并给其传递搜索参数,然后这个Bean访问数据库,选择匹配检索条件的条目,并把记录传回客户程序。通信完成之后,Bean不保留交互信息。因此,多个客户程序可以同时访问无状态会话Bean却不会相互影响。

2)有状态会话Bean

相反,有状态会话Bean会把请求同特定的客户联系起来,在客户和Bean之间建立一种一对一的关系。购物车Bean就是一个特殊的实例:用户往购物车里加入商品,输入地址信息然后下定单,购物车Bean维持状态,因而它知道所有这些变量都关联某一特定客户。

2.Entity Bean——实体Bean

实体Bean表示会话终止之后持久存在的业务对象或者数据。它们通常作为数据库中的单一记录存在,当然,其存储形式也可能采用其他媒介,比如文件等。一个对象就表示一个用户,有名字、联系方式等,这些参数代表了实体Bean的用途。作为持久性最本质的内涵之一,实体Bean的唯一标识或者主键起到了识别和检索正确对象信息的作用。实体Bean需要主键作为“辅助类”封装对象的唯一标识符。

Entity Bean是域模型对象,用于实现O/R映射,负责将数据库中的表记录映射为内存中的Entity对象。事实上,创建一个Entity Bean对象相当于新建一条记录,删除一个Entity Bean会同时从数据库中删除对应记录,当修改一个Entity Bean时,容器会自动将Entity Bean的状态和数据库同步。

注意

实体Bean是EJB 1.x和EJB 2.x中的组件,在EJB 3.x中,已经被JPA所代替。

3.Message-Driven Bean——消息驱动Bean

以上的两种Bean类型以同步方式为EJB客户提供服务。客户发出请求然后等待Bean发回结果。消息驱动Bean避免了这一可能的瓶颈问题。采用Java消息服务JMS(Java Messaging Service),客户程序可以产生一个消息并把消息发布给消息队列。消息驱动Bean随之采用或者检索消息执行其内容。这种事件或者数据的通信就成为异步形式;客户或者Bean都无须依赖对方的直接响应了。

比如,北京的某一个银行使用一种应用程序发布最新的汇率消息。这时,部署在上海的一个外部交易Bean从消息队列中获取这一消息,然后更新数据库中的有关记录。在理想的情况下,消息驱动Bean会把信息传递给处理数据库事务的实体Bean。这样,每一种Bean把它不能处理的任务转发从而创建出一种真正的分布式组件结构。

3.1.5 EJB发展历史

1997年4月12日,Sun发布了一项为企业环境开发Java平台的创新成果。使用开放式的Java Community Process,Sun促进了一组标准的Java扩展的开发,称为Enterprise Java API。这些应用程序编程接口(API)为各种各样的中间件的实现提供了不依赖供应商的编程接口。Enterprise Java API的要点是Enterprise JavaBean API,后者为Java应用程序服务器定义了一个服务器端组件模型,以及一个不依赖供应商的编程接口。

Java EE为Enterprise JavaBean技术提供了工作环境。事实上,Sun把若干项软件技术都设想为这样的构件块,它们将使大型企业能够把以任务为关键的业务系统移植到Java环境中,而Enterprise JavaBean技术不过是这些技术之一。EJB组件是按它们自己的规范定义的,但EJB技术并不是一项独立的技术。它建立在其他的Java技术之上,这些技术由Sun和其他IT公司联合规定,它们一起提供了这个框架的内容,该框架就称为Java 2 Platform,Enterprise Edition。

Java EE中包括以下技术。

● EJB(Enterprise JavaBeans):Java EE中间层,完成商业逻辑。

● JMS(Java Message Service):Java EE的异步消息队列。

● JNDI(Java Naming and Directory Interface):Java EE的名字查找API,独立于目录服务器。

● JCA(Java Connector Architecture):Java EE用于连接异种数据源的API。

● JTS(Java Transaction Service):Java EE用于处理交易的API。

● JTA(Java Transaction API):Java事务API。

● RMI/IIOP(Java Remote Method Invocation):Java EE的分布式对象的通信API,提供了和CORBA交互的能力。

● JPA(Java Persistence API):Java持久化API。

● JDBC(Java Database Connection):Java EE数据库访问。

● IDL(Java Interface Definition Language):Java接口定义语言。

以上Java EE框架中的技术,并不是每项技术都依赖于其他技术。单独的规范文档指出每项技术的相关性。例如,Enterprise JavaBean规范1.0发行版就指明了在定位各个组件时与JNDI的相关性,以及在编程中启动和停止事务处理时与JTA的相关性。

EJB规范的第一版以初稿形式于1997年12月公布,并于1998年3月作为1.0版发行。到现在为止,EJB已经成功地发布到了EJB 3.0版本了。每一次发布都会具有不同的特性。下面我们简单回顾一下EJB的发展历史。

1)EJB 1.0

最初的版本1.0开始支持有状态和无状态的服务器对象(称为会话Bean),以及可选支持持久化域对象(称为实体Bean)。在可移植性方面,EJB通过提供可移植性和远程特性的专门远程接口达到访问的目的,但是受到了远程基础结构和按值传递的语义的开销的影响。

2)EJB 1.1

其后的版本1.1要求厂商支持实体Bean,并且引入XML部署描述文件来替换存储在专门的串行化类文件中的数据。

3)EJB 2.0

EJB 2.0通过引入本地接口弥补远程接口造成的开销和按值传递的缺陷。只有运行在Java EE容器内的客户才能通过其本地接口访问EJB,但是按引用传递的方法调用允许组件之间更加有效地进行交换操作。EJB 2.0还引入了新型的EJB消息驱动Bean(Message-Drive Bean,MDB),能够参与异步消息系统。实体Bean得到了容器管理的关系的支持,允许Bean的开发者声明式地指定由EJB容器管理的实体Bean之间的持久化关系。另外还引入了EJB查询语言EJB QL,它使开发者具有了使用类似于SQL那样的语言来查询实体Bean实例的功能。

4)EJB 2.1

EJB 2.1添加了Web服务的支持,允许会话Bean暴露端点接口,添加了允许按照指定的时间或者时间间隔调用EJB的计时器服务。EJB 2.1还提供了扩展EJB QL的功能,并且引入XML Schema来替换定义了ejb-jar.xml部署描述文件的DTD。

5)EJB 3.0

EJB 3.0最重要的改动是实体Bean被替换为POJO,现在被称为实体,可以运行在EJB容器的外部,因此在实体类本身中不需要专门的接口或者EJB专有的代码。会话Bean不再需要主接口或者EJB专有的组件接口。在逻辑上它们仍然支持远程和非远程接口。这两个改动和很多其他改动都符合EJB 3.0以简化的开发模型为中心的新的设计理念。

从以上的5个版本的发布可以看出,各个版本分别为EJB注入了不同的功能。

● EJB 1.0:会话Bean(有状态和无状态)、实体Bean。

● EJB 1.1:XML部署描述符。

● EJB 2.0:消息驱动Bean(支持JMS)、EJB查询语言EJB QL。

● EJB 2.1:支持Web服务、计时器服务。

● EJB 3.0:简化开发模型。

以上的各个关键字涵盖了EJB的主体功能和技术特性,本书将以最新的EJB 3.0为主进行讲解,后面的章节也将循序渐进地讲解各种技术的开发应用过程。

3.1.6 EJB 3.0新特性

EJB技术是服务器端企业开发的标准。与Java本身一样,EJB改变了开发的方式并且激发了很多创新。EJB 3.0作为最新的版本,更具有下面显而易见的特性。

1)简单易用

EJB 3.0可能是最简单的服务器端开发平台。最值得注意的是POJO程序设计、使用注解而少用冗长的XML、大量使用有意义的默认值,以及JPA。虽然EJB服务的数量众多,但是会发现它们非常直观。在很大程度上,EJB 3.0具有实用的外观并且不要求开发人员了解错综复杂的理论。实际上,大多数EJB服务的目的都是使开发人员脱离这种思维模式,以便集中精力完成工作。

2)方便集成

EJB 3.0提供服务器解决方案的各种集成方案,包括持久化、消息、轻量型计划、远程处理、Web服务、依赖注入(Dependency Injection,DI)和拦截器。因此,开发人员不必花费很多时间寻找第三方工具并将其集成到应用程序中。此外,EJB 3.0提供与其他Java EE技术的无缝集成,比如JDBC、JavaMail、Java事务API(Java Transaction API,JTA)、Java消息服务(Java Messaging Service,JMS)、Java验证和授权服务(Java Authentication and Authorization Service,JAAS)、Java命名和目录接口(Java Naming and Directory Interface,JNDI)、Java远程方法调用(Java Remote Method Invocation,RMI)等。EJB也保证与表现层技术的无缝集成,比如Java Server Page(JSP)、Servlet、Java Server Face(JSF)和Swing。

3)开放的Java EE标准

EJB是Java EE标准的关键部分。EJB 3.0有开放的、公共的API规范,组织机构鼓励使用它创建容器或持久化提供器实现。EJB 3.0标准是Java Community Process(JCP)开发的,开放标准使更多的厂商支持EJB 3.0,这就意味着不必依赖专有的解决方案。

4)广泛的厂商支持

EJB被数量众多的各种各样的独立机构支持,包括技术领域中最大、最受尊重的和财力最雄厚的大公司,比如Oracle和IBM,以及充满热情和活力的开源组织,比如JBoss和Geronimo。

广泛的厂商支持带来3大重要优势。首先,我们不会受到个别公司或组织的兴衰的影响。其次,大量人员的长期投入使这种技术尽可能保持竞争力。从本质上讲,在这个充满竞争的时代,可以充分利用Java和Java以外的各种技术的优势。另外,厂商在过去的相互竞争中提供了具有附加值的非标准特性。所有这些因素让EJB继续健康向前发展。

5)稳定的系统基础

虽然EJB 3.0是开创性的一步,但是大多数应用程序服务器实现仍然受益于相对稳定的代码基础。长期以来,这些代码基础经受了一些要求最为苛刻的企业环境的考验。大多数持久化解决方案(比如JDO、Hibernate和TopLink)也是稳定的产品,在很多任务关键型的产品型环境中使用过。这就是说,虽然EJB 3.0非常新,但是我们可以期望较快地得到稳定的实现。此外,由于基于标准的开发的本质,厂商一般会重视EJB 3.0容器实现的质量。在某种意义上,它有利于保证内在的实现质量。

6)易于集群、负载平衡和故障转移

大多数应用程序服务器厂商增加的特性对集群、负载平衡和故障转移提供了有力的支持。历史证明,EJB应用程序服务器支持一些最大型的支持高性能计算(High-Performance Computing,HPC)的服务器集群环境。更重要的是,不必修改代码,不需要集成第三方工具,通过相对简单的配置(在创建硬件集群的固有工作之外),我们就可以利用这样的支持。这就是说,如果有需要,我们可以依靠硬件集群使用EJB3.0扩展我们的应用程序。