当前位置导航:炫浪网>>网络学院>>编程开发>>Oracle教程

如何在ORACLE服务器中开发和布署企业级JavaBeans(下)

我们已经介绍了Oracle环境中支持的Oracle JServer和组件模型。现在,让我们看看如何在在Oracle中实现企业级JavaBean。这一部分,将完整地、一步一步详细地向你介绍如何在Oracle8i 数据库里开发和布署企业级JavaBean。由于企业级JavaBean 拥有纯Java 的定义,所以用户不必使用IDL 来定义对象接口。所有的接口都是使用Java定义的。

在我们进入EJB的范例之前,我们先简要地概括一些有关状态、持久性和不同企业级JavaBean类型的概念。

*持久数据 -  数据位于持久的存储机构里。数据是事务性的,是共享的。持久存储机构的实例就是传统的数据库和面向对象的数据库。持久数据的实例就是关系数据库表中的某一行,或者面向对象数据库中的某一页对象。
*持久数据的事务性共享,是由持久存储机构处理的;同时,EJB运行时的事务性服务,被用来保证持久数据的ACID属性。
*过渡数据 -  数据仅位于企业 bean 自身。在持久存在机构里,不反映过渡数据,过渡数据属于企业bean实例私有。
*持久状态缓存 -  企业bean用来操纵持久存储机构里数据的高速缓存。所以,持久缓存代表持久数据,但并不是持久数据。开发人员利用划分事务启始的钩子,提供了持久数据的连贯视图。
*会话状态 -  缓存的持久数据和临时数据二者的混合。
企业级JavaBean 规范描绘了三种类型的bean (无状态会话bean,有状态会话 bean,和实体 bean),这三种类型的划分,主要是根据bean如何保持它们的状态。EJB容器管理bean的状态,bean的状态引用包含在bean里的数据。

会话Bean
会话 bean 是由客户建立的,多数情况下,只存在于单一客户-服务器会话期间。会话 bean 代表客户执行操作,例如访问数据库或者执行计算。会话 bean,也称为过渡bean,可以是事务性的。但是在系统崩溃之后,会话bean不能恢复。有二种会话bean:

*无状态会话 Bean  -  在方法和事务之间,不维持会话状态的 bean。EJB 服务器透明地重用这个bean的实例,为不同的客户提供服务。
*状态会话 Bean  -   在方法和事务之间,维护会话状态的bean。这样,EJB 服务器会直接把企业 Bean 的实例绑定到客户。根据定义,会话bean不是持久的,虽然在它里面可能包含需要保持的信息。会话 bean 能够在企业bean的方法里,直接实现持久性操作。会话 bean 经常要维护数据库信息的一份缓存,这些信息在事务开始、提交或中止时,必须与数据库同步。在Oracle8i中,可以使用JDBC或SQLJ实现这样的状态同步。SQLJ 是Java程序里嵌入SQL语句的标准方法。

 

实体 Bean
实体bean也称为持久bean。实体bean 拥有一个标识,所以一般来说,当建立它们的容器崩溃或重新启动时,它也能保持不变。容器为在它里面建立的EJB对象提供了安全性、并发能力、事务处理、持久性以及其它服务,这些对客户来说都是透明的。多个客户能够并发地访问一个实体对象。安装实体bean的容器,负责同步对实体状态的访问。

实体 Bean 是企业级JavaBean规范的可选部分,规范的这部分还没有完全实现标准化。所以,Oracle8i 并不支持它们。Oracle8i只支持会话Bean。Oracle计划在未来的发行版里支持实体bean。

 

编写JAVA 代码
现在,我们看看开发企业级JavaBean的步骤。开发人员需要给客户程序定义四个项目,才能激活包含商业逻辑的bean的方法。在这一部分,我们以大家熟悉的银行帐户作为例子。在这个例子使用的帐户bean 主要有二个功能:给出帐户的余额,借记帐户。

1. 定义远程接口

由于企业级JavaBean 能被远程调用,所以开发人员要做的第一件事,是定义EJB的远程接口。远程接口把客户能够调用的bean的所有方法或公共接口列出来。虽然在EJB规范里,bean的远程接口被定义为标准的Java RMI (远程方法调用) 接口,但实际的通信是独立于RMI的。Oracle8i用IIOP 作为通信协议。远程接口定义与CORBA对象的IDL定义类似。下面是为帐户bean定义远程接口的例子:

// Bean 的远程接口扩展了javax.ejb.EJB对象
// 所有的方法都抛出(throw) java.rmi.RemoteException 远程异常
public interface Account extends javax.ejb.EJBOBJECT {
float getBalance () throws java.rmi.RemoteException;
void debit (float amount) throws java.rmi.RemoteException;
}
2. 定义当地接口(home interface)

因为可以在远程服务器上调用bean,所以仅仅使用Java的 ‘new’(新建)方法,就想在远程服务器上建立对象是不够的。Bean 必须为客户提供一种机制,使客户能够建立bean的实例。通常,这些接口叫做对象或bean代理。当地接口就充当了EJB的代理接口。当地接口中定义了零个或多个create(...) 方法,每个方法代表一个建立EJB对象的途径。客户可以调用这个代理接口,建立bean的实例。开发人员只需定义代理接口,不必实现代理接口的每个方法。在布署阶段,供bean当地接口使用的服务器端实现类,会自动生成,生成的实现,是由特定EJB服务器提供的,因此能够充分利用EJB服务器的专长。在 Oracle8i中,通过Oracle提供的自动处理工具,在EJB装入数据库时,会自动生成这些实现。

// Bean 的当地接口扩展了 javax.ejb.EJBHome 接口
public interface AccountHome extends javax.ejb.EJBHome {
Account create (String account) throws
java.rmi.RemoteException,
javax.ejb.CreateException;
}
3. 定义 Bean 自身

bean 本身是一个标准的Java 应用程序,它实现了bean开发人员编写的商业逻辑。在应用程序的代码里,用户无需描述bean的事务性和安全性语义。使用bean的布署描述器,可以用宣告的方式,描述它们。由于Oracle8i 支持会话 bean,所以用户无需显式地保持bean的状态。由于Oracle Jserverr的EJB 服务器与Oracle的DBMS紧密地集成在一起,所以用户通过JDBC或SQLJ管理bean的持久状态。

//Bean 自身是实现所有商业逻辑的地方。
public class AccountBean implements javax.ejb.SessionBean {


// Bean 的接口方法
public float getBalance () {


// 在此加入具体的实现代码

}
public void debit (float amount) {
//在此加入具体的实现代码

}


// 当地接口方法,这些方法要与当地接口中定义的方法一一对应。
// 这些方法由应用程序的开发人员实现。


public void ejbCreate (String account) {…}
}
4. 定义Bean 的布署描述器

编写bean所需要的全部代码,就是定义上面的接口和类。bean 的布署描述器把bean的不同组件捆绑在一起。布署描述器是一种Java串行化对象,它扩展了布署描述器基类,允许用户以宣告的方式指定bean的事务和安全属性,从而简化了建立操作数据库的事务性应用程序的过程。bean的属性可以在bean一级指定,也可以用方法描述器,在bean的方法一级上指定更加细致的事务和安全属性。Oracle 提供了指定bean布署描述器的特殊语法。EJB 规范要求布署描述器保存在串行化对象里。但是,建立布署描述器的串行化实例是非常烦人的,所以我们的工具接受文件的布署描述器,并自动建立串行化对象。文本格式的语法,被设计得看起来就象Java类,而且语法以一个会话Bean语句开始。会话Beasn语句后面跟着企业级JavaBean的完整规范类名。

描述器就是一列bean的属性,它的一般格式是:

<属性名称> = <属性值>;

 

有三种类型的bean属性:

Bean自身的属性– 例如:它的事务和安全属性、JNDI 名称、以及它的远程和当地接口名称。某些属性是必需的(必需属性的详细列表,请参阅Oracle的相关文档)。
 Bean的方法的属性– 与事务和安全有关的属性,可以在bean的方法上单独指定。我们要用标准Java语法,以文本格式确定方法的签名,但是要用一组方法属性填充方法的内容。方法的修饰符,例如public 或 static,方法的返回类型以及方法的参数名称都是可选的、可忽略的。
Bean的环境属性– 在bean描述器里,使用一个名为环境属性EnvironmentProperties 的条目指定Bean的环境属性。解释器根据列中建立属性对象,把它作为bean描述器的环境属性EnvironmentProperties供系统使用。
下面是一个建立布署描述器的示例:

// 帐号Bean的Bean 布署描述器
SessionBean AccountBean {
BeanHomeName = "bn=myAccount"; // 必需属性
RemoteInterfaceClassName = Account; //必需属性
HomeInterfaceClassName = AccountHome; //必需属性
AllowedIdentities = {PUBLIC};
SessionTimeout = 3000;
StateManagementType = STATELESS_SESSION;
TransactionAttribute = TX_MANDATORY;
IsolationLevel = TRANSACTION_READ_UNCOMMITTED;
public void getBalance ()
{
RunAsIdentity = WENDY;
}
public void debit (float amount)
{
AllowedIdentities = {TELLER};
TransactionAttribute = TX_REQUIRES_NEW;
}
EnvironmentProperties
{
MinInitialBalance = 100.00;
}
}
编译、打包JAVA代码
编写完上面提到的类、接口和布署描述器之后,现在需要执行下列步骤:

1. 编译代码

必须把EJB 本身、它的远程接口、以及它的当地接口编译为Java类。

// 把Bean、远程接口、当地接口编译为Java类
% javac AccountBean.java Account.java AccountHome.java …
2. 打包类文件

下一步,需要把EJB打包,这样它才能布署到Oracle8i里。打包EJB的关键是:把编译后的EJB、远程接口、当地接口的类文件归档进EJB包— 一个标准的Java jar 文件里。

// 把类文件打包进一个EJB包
% jar cf Account.jar *.class
3. 增加布署描述器

最后,必须给bean增加EJB布署描述器,以宣告的方式指定它的事务和安全属性。方法是,使用命令行工具“createejb” 把给jar加上描述器。

// 加入在Account.dsc文件里指定的EJB 布署描述器
// 使用Oracle提供的createejb 工具
% createejb Account.jar -desc Account.dsc


把 EJB 布署进ORACLE 数据库
打包之后,就做好了把企业级JavaBean布署进Oracle8i 服务器的准备。要在Oracle8i上布署EJB,需要使用Oracle提供的布署工具 “deployejb”。这个工具会自动完成在Oracle8i上布署EJB的过程,实现了单步布署。这个工具自动进行三个相关动作:

1. 生成服务器端运行时代码

首先,这个工具自动生成EJB 服务器端运行时代码。它自动分析EJB布署描述器,并建立Oracle Jserver的EJB服务器所必需的宣告性安全和事务信息。然后,它把服务器端运行时代码上载到Oracle8i里。由于EJB 本身已经打包成标准的Java .jar文件,所以这个过程通过Oracle 提供的LOADJAVA工具自动进行。

2. 生成客户端类

第二步,工具自动生成访问EJB服务器所必需的客户端类。它实现了与服务器无关的接口,并把它们输出为新的jar文件(Accountclient.jar)。

3. 执行附加的设置

第二步,工具自动执行在数据库里布署EJB所需要的额外设置步骤。设置需要执行以下过程:

添充EJB布署描述器里说明的JNDI可访问名称服务
为Bean的RunAs属性强制实施安全性
生成通信支持代码
下面是一个布署EJB的示例:

// 使用deployejb工具布署EJB
// 用户名是要在里面布署EJB的大纲(schema),
// 服务名是要布署Bean的服务上下文。
% deployejb -u <用户名> -p <口令> -s <服务名> -gen
Accountclient.jar Account.ja


编写EJB 客户
在成功地完成了上面提到的步骤之后,EJB就已经布署成功。现在可以从客户端激活它,为这个EJB编写客户端需要三个步骤:

1. 认证客户身份

EJB 布署在数据库里。数据库是一个安全的环境。所以,在激活任何EJB之前,首先必需要用 Oracle8i 服务器确认客户的身份。有几种方法做这个工作:

显式认证 -  客户首先通过‘Login’登录bean,进行数据库的身份认证。‘Login’登录 bean 是客户激活其它bean之前唯一能够访问的bean。然后,客户可以调用这个bean的认证方法,提供用户名、口令和角色。当‘Login’登录bean 成功地把客户登录进Oracle 数据库之后,客户就可以使用它有权访问的其它bean了。任何 Java 客户都可以使用这种机制。
隐式认证 -  要访问企业级JavaBean,客户也可以用它的用户名、口令和角色初始化一个‘Credential’ 凭据对象。随着第一个IIOP消息,这些信息被发送给服务器。这种技术类似于传递事务的上下文环境。服务器根据接收到的凭据,在数据库里检测用户名和口令。在没有验证有效凭据之前,数据库不允许客户进行任何进一步的访问。
基于SSL的认证 -  除了基于口令的认证, Oracle的企业级JavaBean 容器还提供了对安全套接字 (SSL) 支持,对SSL的支持是可选的。这一特性允许进行比基于口令的认证更强大的认证。它还提供了保密性和数据完整性,这些都是基于口令的认证方式无法做到的。目前Oracle仅支持使用SSL的加密和服务器端认证。
2. 定位Bean的当地位置

用户得到数据库的认证授权后,下一步就是找到Bean在服务器上的位置,并通过标准的bean接口访问它。客户从标准目录或者通过JNDI的名称服务找到bean的当地位置。

3. 生成Bean的实例,激活方法

通过调用bean的当地接口,客户现在可以建立bean的实例。当地接口充当着bean的代理,根据客户的请求建立实例。Bean的实例建立之后,用户通过调用远程接口中发布的Bean的方法,就能执行实例的方法。从EJB布署时生成的.jar文件里,客户获得bean的远程接口。客户可以用两种方式控制事务:一种是依靠作为EJB布署一部分所指定的宣告事务;另一种是利用Java的事务服务 (JTS),显示地驱动来自bean客户的事务。

下面是客户使用Credential凭据对象取得数据库认证的示例:

// 实现EJB 客户对服务器 bean的访问
// 请注意:为了保持代码简洁,我们没有捕获任何异常,
// 在具体使用时,你必须在自己的代码里加上这些处理。
public class AccountClient {
// Authenticate using Credential Object
public float debit_account(float amount, String aname) {
String uname = “scott”;
String password = “tiger”;
Credential.authenticate(“uname”,“password”);
// Create a new Initial context for use with JNDI
InitialContext ctx = new InitialContext (…);
// 用当地接口建立Bean的实例
AccountHome ahome = (AccountHome) ctx.lookup (“… bn=myAccount”);
// 现在有了帐户的代理,可以使用create方法建立帐户对象
Account new_account = ahome.create(aname);
// 调用Bean的接口
new_account.debit(amount);
float balance = new_account.getBalance ();
return (balance);
}
}


从企业级JavaBeanS访问持久数据
迄今为止,我们已经讨论了在Oracle8i 数据库里如何开发和布署企业级JavaBean。在上面简单示例的帮助下,我们演示了在数据库里建立、打包和布署EJB所需要的步骤。但是,我们使用的例子太简单了,里面没有访问Oracle数据库里任何持久状态的操作。在这一部分里,我们要看看EJB如何访问持久数据。

运行在数据库里的企业级JavaBean 可以利用JDBC 或 SQLJ 访问持久数据。Oracle的 Java 虚拟机,有在数据库里运行的特殊JDBC驱动程序版本。这种内嵌在Oracle里的JDBC驱动程序符合JDBC 1.22 规范,而且支持与客户JDBC驱动程序相同的API。由于这个JDBC 运行在与数据库相同的地址和进程空间里,所以它们被优化成可以直接访问SQL,不必再经过任何网络迂回。

 

企业级JavaBeanS的好处
企业级JavaBean 与CORBA、DCOMC或传统的过程化编程方式相比,提供了多种好处。首先,我们看看企业级JavaBean提供的好处。然后,我们再介绍使用Oracle8i 布署EJB 应用程序的好处。

易于编程
对于 Java 开发人员,EJB明显比其它组件系统,例如CORBA或DCOM,更容易编程,具体有以下原因:

*没有新的IDL  -  由于企业级JavaBean 拥有纯 Java 的定义,所以用户无需了解外部IDL。EJB 支持任何有效RMI类型按值进行的对象引用,允许传送值参,而不必使用引用传递。
*宣告的事务规则 -  可以在组装应用程序时定义EJB的事务规则,也可以在布署时定义它。事务的语义,以宣告的方式定义,而不是以编程的方式定义。EJB 服务器根据与EJB关联的布署描述器中指定的事务属性,代表EJB自动地管理事务的启动、提交和回卷。EJB规范提供了多种事务策略供用户选择:BEAN_MANAGED, NOT_SUPPORTED, SUPPORT, REQUIRES,REQUIRES_NEW,以及MANDATORY。这些不同的策略使EJB可以采取不同类型的行为。
*宣告的安全性 -  与上一项类似,EJB上的安全策略可以用宣告的方式指定。
*无需系统级编程 -  也是最后一点,EJB 开发人员无需处理低级的系统编程问题,例如与线程相关的编程。至于规模性需求,则由EJB服务器的实现自动解决了。
容易布署
EJB 很容易在多层、分布式的环境里布署:

EJB 客户与服务器的实现无关 -  布署过程自动地建立EJB客户类和和管道(stub)。而且,客户实现了与服务器无关的接口。这样,客户就不必顾虑选择哪个EJB服务器实现。其它一些因素,例如用宣告的机制指定安全性,使得布署EJB的时候可以修改安全属性。
高度的自定义 -  与JavaBean类似,EJB 组件模型支持不需要访问源代码的自定义。而且,用宣告的方式指定事务和安全行为的能力,在布署阶段就能自定义事务和安全性。
开发人员付出有限精力,就可实现大规模
EJB 允许服务器应用程序的规模,只需开发人员付出有限的精力,就可以扩大规模。这是因为EJB的定义,为了允许服务器规模性,特意做了限制。企业级JavaBean 环境自动地采用复杂的基础框架服务,例如:线程管理。组件开发人员和应用程序制作人员无需在应用程序的编程逻辑里实现复杂的服务功能。

EJB是可移植的
用EJB定义的服务器逻辑,可以移植到不同的 EJB 服务器。EJB的设计,就是设计成能够跨Java 虚拟机进行移植。EJB服务器,要以三个形式符合标准EJB规范:

标准的EJB包格式 -  -  所有的 EJB 服务器都接受标准格式的EJB,EJB的标准格式叫做ejb包格式。Oracle8i 接受这种格式的包。这些包是用EJB布署工具‘deployejb’建立的,‘deployejb’自动在Oracle RDBMS上布署EJB,并在装入期间生成适合特定服务器的代码。
独立于布署容器 -   EJB 模型定义了EJB组件和EJB容器系统之间的关系。EJB无需使用特定的容器系统。任何应用程序执行系统,加上对EJB规范里定义的服务的支持,都能适应支持EJB的任务。服务定义了企业bean和容器之间的合约,有效地实现了一个移植层。EJB 本身和EJB 客户程序的编写,都不依赖布署它们的服务器。正因为如此,它们能够很容易地从一个 EJB 服务器移动到分布式环境中的另一台服务器上。
宣告式的编程 -  由于EJB用宣告的方式指定事务,应用程序本身不需要显式的事务代码,所以 EJB能够跨不同的事务管理器进行移植。
开放、标准的服务器组件模型
最后,EJB作为开放的、分布式的、针对Java的、面向服务器的组件模型,拥有巨大的推动力和广泛的业界支持。多数主要厂商,包括Oracle、IBM、Sybase、Netscape和BEA Systems,都参与了企业级JavaBean规范的定义。这些厂商都已经提出了在它们产品中实现企业级JavaBean支持的计划。并且, EJB 是一个开放的、跨平台的组件模型,它不同于微软的 DCOM这样的专用组件模型,DCOM是专门用于Windows 平台的。

现在我们看过了EJB的种种好处,该看一看Oracle8i 给EJB 开发人员提供的特别的好处了。

规模性
首先,EJB 组件是能够利用Oracle JServer共享内存优化和Oracle8i 多线程服务器基础架构的标准Java 应用程序。这种合作,使EJB的规模达到了超过10000个并发客户。第二,不管并发运行的实例如何多,EJB的不变部分,包括它的元数据和初始原始,被放在共享内存里,只放一次,并在所有的EJB实例间共享。这两项特性,与其它一些优化措施组合在一起,为Oracle Jserver EJB服务器提供了空前的规模性。

高性能
Oracle的EJB 服务器的多个特性提供了高性能。由于EJB 是标准Java应用程序,所以利用Oracle Jserver提供的各种性能优化措施,能使Java执行起来非常迅速。

有效地访问SQL  -  由于EJB 使用Oracle内嵌的JDBC驱动程序访问RDBMS里的持久状态,所以对 SQL 数据的访问非常有效率。Oracle8i 为数据密集型EJB提供了理想的EJB 服务器平台。
Oracle Jserver加速器 (本机编译)  -  由于 EJB 是标准Java程序,所以它们能够利用Java到C的转换器,以及其它 Java 虚拟机优化技术,从而显著地提高性能。
易于使用
EJB 事务到传统 RDBMS 事务的映射,为用户提供了熟悉而且性能很高的事务协调机制。把EJB 作为编程式样,用户现在能够以宣告的方式,而不是以编程的方式指RDBMS事务。EJB的安全性也映射到传统 RDBMS 用户和角色。由此,Oracle提供了高度安全的EJB 服务器。

集成的工具
自动化的EJB 布署工具,使得在Oracle8i上打包和布署 EJB 应用程序非常容易。而且,这些工具都和Oracle’s JDevelop ™的IDE环境集成在一起,从而促进和简化了应用程序的开发过程。Oracle还提供了一套EJB 服务器管理工具,用户利用它,可以对布署在服务器上的EJB执行不同的模拟和管理工作。

安全
对于布署在Oracle8i数据库里的企业级JavaBean,可以使用多种安全机制。应用程序开发人员可以自由选择使用传统的基于用户名/口令的认证机制,还是传统RDBMS特权机制的SQL级安全性,或者通过SSL的网络级加密机制。

 

总结
这份白皮书就如何开发企业应用程序,例如企业级JavaBean以及布署在Oracle8i 数据库中布署它们,做了一次快速的概述。Oracle8i数据库集成的Java 引掣—Oracle JServer,为布署大规模、强壮、安全、高可用、易于管理的应用程序提供了开放的服务器平台。

企业级JavaBean 提供了强壮的服务器端组件模型,允许开发人员通过装配不同厂商的组件来建立应用程序。这让开发人员能够迅速地使应用程序适应迅速变化着的商业需求。企业级JavaBean宣告形式的编程模型让开发人员能够把精力集成在开发逻辑,而不是系统编程的问题上。

简而言之,在Oracle 数据库里使用企业级JavaBean ,需要四个步骤:

*定义自己的:
*远程接口
*当地接口
*Bean
*布署描述器
*编译、打包Bean
*在Oracle 服务器布署Bean
*编写调用Bean方法的客户应用程序
由于Java 与数据库服务器运行在相同的地址空间,而且使用数据库内嵌的JDBC驱动程序,所以它们访问SQL数据时不需通过网络迂回,而且,正因为如此,被优化成提供高性能。Java 与数据库的集成很紧密,能够无缝地与SQL和PL/SQL互操作。

Oracle实现的企业级JavaBean 给开发人员提供了种种的好处,其中包括大规模性、高性能、高可用性、应用程序的高吞吐量,以及Java、SQL和PL/SQL间无缝的互操作性。

相关内容
赞助商链接