现在的位置: 首页 > 综合 > 正文

第九讲 JavaBean和RMI

2013年08月18日 ⁄ 综合 ⁄ 共 9100字 ⁄ 字号 评论关闭

【课前思考】
  1. 什么是JavaBean?
  2. JavaBean和Java有什么关系?
  3. JavaBean会有什么样的用途?
  4. 什么是RMI?
  5. RMI技术会有什么样的特点?
  6. 什么是EJB?
  7. EJB和JavaBean又有什么样的关系?

9.1 JavaBean的基本概念
9.1.1 JavaBean产生的背景介绍

软件组件就是指可以进行独立分离、易于重复使用的软件部分。JavaBean就是一种基于Java平台的软件组件思想。JavaBean也是一种独立于平台和结构的应用程序编程接口(API)。JavaBean保留了其他软件组件的技术精华,并增加了被其他软件组件技术忽略的技术特性,使得它成为完整的软件组件解决方案的基础,并在可移植的Java平台上方便地用于网络世界中。

9.1.2 JavaBean基本概念

虽然JavaBean和Java之间已经有了明确的界限,但是在某些方面JavaBean和Java之间仍然存在很容易混淆的地方,比如说重用,Java语言也可以为用户创建可重用的对象,但它没有管理这些对象相互作用的规则或标准,用户可以使用在Java中预先建立好的对象,但这必须具有对象在代码层次上的接口的丰富知识。而对于JavaBean,用户可以在应用程序构造器工具中使用各种JavaBean组件,而不需要编写任何代码。这种同时使用多个组件而不考虑其初始化情况的功能是对当前Java模型的重要扩展,所以也可以说JavaBean是在组件技术上对Java语言的扩展。
  如果真的要明确的定义,那么JavaBean的定义是:JavaBean是可复用的平台独立的软件组件,开发者可以在软件构造器工具中对其直接进行可视化操作。在上面的定义中,软件构造器可以是Web页面构造器、可视化应用程序构造器、GUI设计构造器或服务器应用程序构造器。而JavaBean可以是简单的GUI要素,如按钮和滚动条;也可以是复杂的可视化软件组件,如数据库视图。有些JavaBean是没有GUI表现形式的,但这些JavaBean仍然可以使用应用程序构造器可视化地进行组合,比如JBuilder上的很多控件其实也是没有GUI形式的,但是你仍然可以拖放它们以在你的应用程序里生成相应的代码。一个JavaBean和一个Java Applet很相似,是一个非常简单的遵循某种严格协议的Java类。
 
 JavaBean具有Java语言的所有优点,比如跨平台等等,但它又是Java在组件技术方面的扩展,所以说很多方面它和Applet很像,Applet也具有Java语言的所有优点,同时也是Java在浏览器端程序方面的扩展。其实它们都是严格遵循某种协议的Java类,它们的存在都离不开Java语言的强大支持。

9.1.3 JavaBean的属性、事件和方法

从基本上来说,JavaBean可以看成是一个黑盒子,即只需要知道其功能而不必管其内部结构的软件设备。黑盒子只介绍和定义其外部特征和与其他部分的接口,如按钮、窗口、颜色、形状等。作为一个黑盒子的模型,以把JavaBean看成是用于接受事件和处理事件以便进行某个操作的组件建筑块。

一个JavaBean由3部分组成:
   (1) 属性(properties)
  JavaBean提供了高层次的属性概念,属性在JavaBean中不只是传统的面向对象的概念里的属性,它同时还得到了属性读取和属性写入的API的支持。属性值可以通过调用适当的bean方法进行。比如,可能bean有一个名字属性,这个属性的值可能需要调用String getName()方法读取,而写入属性值可能要需要调用void setName(String str)的方法。
  每个JavaBean属性通常都应该遵循简单的方法命名规则,这样应用程序构造器工具和最终用户才能找到JavaBean提供的属性,然后查询或修改属性值,对bean进行操作。JavaBean还可以对属性值的改变作出及时的反应。比如一个显示当前时间的JavaBean,如果改变时钟的时区属性,则时钟会立即重画,显示当前指定时区的时间。
  (2) 方法(method)
  JavaBean中的方法就是通常的Java方法,它可以从其他组件或在脚本环境中调用。默认情况下,所有bean的公有方法都可以被外部调用,但bean一般只会引出其公有方法的一个子集。
  由于JavaBean本身是Java对象,调用这个对象的方法是与其交互作用的唯一途径。JavaBean严格遵守面向对象的类设计逻辑,不让外部世界访问其任何字段(没有public字段)。这样,方法调用是接触Bean的唯一途径。
  但是和普通类不同的是,对有些Bean来说,采用调用实例方法的低级机制并不是操作和使用Bean的主要途径。公开Bean方法在Bean操作中降为辅助地位,因为两个高级Bean特性--属性和事件是与Bean交互作用的更好方式。
  因此Bean可以提供要让客户使用的public方法,但应当认识到,Bean设计人员希望看到绝大部分Bean的功能反映在属性和事件中,而不是在人工调用和各个方法中。
  (3) 事件(event)
  Bean与其他软件组件交流信息的主要方式是发送和接受事件。我们可以将bean的事件支持功能看作是集成电路中的输入输出引脚:工程师将引脚连接在一起组成系统,让组件进行通讯。有些引脚用于输入,有些引脚用于输出,相当于事件模型中的发送事件和接收事件。
  事件为JavaBean组件提供了一种发送通知给其他组件的方法。在AWT事件模型中,一个事件源可以注册事件监听器对象。当事件源检测到发生了某种事件时,它将调用事件监听器对象中的一个适当的事件处理方法来处理这个事件。

9.1.4 JavaBean的特征

JavaBean1.0指定的组件模型规定了Bean的如下特征:
  (1)内省:使组件可以发表其支持的操作和属性的机制,也是支持在其他组件中(如Bean的开发工具)发现这种机制的机制。
  (2)属性:在设计Bean时可以改变的外观和行为特征。开发工具通过对Bean进行内省来获知其属性,进而发布其属性。
  (3)定制:Bean通过发布其属性使其可以在设计时被定制。有两种方法支持定制:通过使用Beans的属性编辑器,或者是使用更复杂Bean定制器。
  (4)通信:Bean之间通过事件互相通信。开发工具可以检测一个Bean可以接收和引发的事件。
  (5)持续:使Bean可以存储和恢复其状态。一个Bean的属性被修改以后,可以通过对象的持续化机制保存下来,并可以在需要的时候恢复。
9.1.5 JavaBean
特征实现的简介

1 属性
  Bean的属性描述其外观或者行为特征,如颜色、大小等。属性可以在运行时通过get/set方法取得和设置。最终用户可以通过特定属性的get/set方法对其进行改变。例如,对于Bean的颜色属性,最终用户可以通过Bean提供的属性对话框改变这个颜色属性。颜色的改变实际上是通过下面的方法实现的:
    public Color getFillColor();
    public void SetFillColor(Color c);
  这种基本的get/set方法命名规则定义的属性叫做简单属性。简单属性中有一类用boolean值表示的属性叫布尔属性。
  JavaBean API还支持索引属性,这种属性与传统Java编程中的数组非常类似。索引属性包括几个数据类型相同的元素,这些元素可以通过一个整数索引值来访问,因此称为索引属性。属性可以索引成支持一定范围的值,这种属性属于简单属性。索引用int指定。索引属性有4种访问方式,其数值数组可以一个元素访问,也可以整个数组访问:

    public void setLabel(int index,String label);
    public String getLabel(int index);
    public void setLabel(String []labels);
     public String []getLabels();
  与标准的Java数组类似索引值可能会在索引属性数组的范围之外。这时,用于操作索引属性的访问者方法一般是抛出一个ArrayIndexOutOfBoundsException运行环境异常,这个异常与标准Java数组索引超出范围时执行的行为相同。
  与简单属性相对的是关联属性和限制属性。这两种属性在运行或者设计时被修改后,可以自动地通知外部世界,或者有能力拒绝被设置为某个数值的属性。关联属性在属性发生改变时向其他beans和容器发出通知。关联属性在发生改变时产生一个PropertyChangeEvent事件,传递给所关联的注册了PropertyChangeListener的听众。可以通过下述方法注册或撤销多路广播事件听众:
   public void addPropertyChangeListener(PropertyChangeListener l);
   public void removePropertyChangeListener(PropertyChangeListener l);
  PropertyChangeListener是一个接口,当相关的外部部件需要与一个属性相关联时,它必须调用addPropertyChangeListener()方法提供一个合适的实现了PropertyChangeListener接口的对象。PropertyChangeListener接口用于报告关联属性的修改,尤其是当一个关联属性值发生变化时,就调用所有注册的PropertyChangeListener接口上的propertyChange()方法。这个方法接受一个PropertyChangeEvent对象,这个对象包含了关于要修改的特定属性的信息及其新值和旧值。
  JavaBean API还支持另一种方法用于注册监听器与特定的关联属性。如果一个bean开发者要在单个属性基础上提供监听器注册,他必须为每个这样的属性支持一对方法:add<PropertyName>Listener()和remove<PnropertyName>Listener()。这对方法工作起来就像前面介绍的那对全局事件监听器注册方法,只是这两个方法是用于特定的属性。下面的一个例子中定义了一个名为Name的关联属性的这两个方法:
    public void addNameListener(PropertyChangeListener l);
    public void removeNameListener(PropertyChangeListener l);
  当bean外部相关部件要将其本身注册到Name属性上时,它只需简单地调用addNameListener()方法来注册它本身。当Name属性修改时,会通过调用propertyChange()方法发送一个通知给事件监听器。这种情况与前面介绍的一样,只是这里的监听器只接收关于Name属性的通知。
  限制属性是内部验证的,如果不合格会被拒绝。用户可以通过异常获知拒绝的属性。限制属性用VetoableChangeListener接口验证改变。可以用如下方法注册或撤销该接口:
    public void addVetoableChangeListener(VetoableChangeListener v);
    public void removeVetoableChangeListener(VetoableChangeListener v);
  限制属性和关联属性的处理机制是很类似的,当属性的修改值到达监听器的时候,监听器可以通过抛出PropertyVetoException异常选择拒绝属性的修改。如果抛出了一个异常,这个bean就要负责处理这个异常并恢复这个限制属性的原来的值。
  与关联属性类似,限制属性也支持单个属性的事件监听方法。下面是一个例子:
    public void addNameListener(VetoableChangeListener l);
    public void removeNameListener(VetoableChangeListener l);
 
2 内省和定制
  
Bean通常被开发成一般化的组件,由开发人员在建立应用程序时配置。这是通过JavaBeans API伴随的两种Java技术实现的。第一种是Java反映API,是一组用于透视类文件和显示其中的属性和方法的类。第二种是Java串行化API,用于生成类的永久存储,包括其当前状态。这两种技术用于使Beans可以用建立工具探索和显示,并修改和存放起来,供特定应用程序使用。

  JavaBean的内省过程显示Bean的属性、方法和事件。内省过程实际上很简单,如果有设置或取得属性类型的方法,则假设Bean有该属性,可以采用如下方法:
    public <PropertyType> get<PropertyName>();
    public void set<PropertyName>(<PropertyType> p);
  如果只发现一个get/set方法,则确定PropertyName为只读或只写。
  除了上述这种内置的内省和定制方法外,JavaBean API还提供了显示的接口BeanInfo,用于Bean设计者显示Bean的属性、事件、方法和各种全局信息。可以通过实现BeanInfo接口定义自己的Bean信息类:
    public class myBeanInfo implements BeanInfo..
  BeanInfo接口提供了一系列访问Bean信息的方法,Bean开发者还可以提供BeanInfo类用于定义Bean信息的专用描述文件。
 3 持续

  JavaBean是依赖于状态的组件,状态可能因为运行时或开发时的一些动作而发生改变,当Bean的状态改变时,设计人员可以保存改变的状态,这种机制叫JavaBean的持续。
  JavaBean状态的持可以通过java对象的串行化机制自动保存,也可以由设计者通过定制其串行化控制Bean对象的状态的保存。

 4 事件
  JavaBean通过传递事件在Bean之间通信。Bean用一个事件告诉另一个Bean采取一个动作或告诉其状态发生了改变。事件从源听众注册或发表并通过方法调用传递到一个或几个目标听众。
  JavaBean的事件模型类似AWT的事件模型。JavaBean中的事件模型是用事件源和事件目标定义的。事件源就是事件的启动者,由它触发一个或多个事件目标。事件源和事件目标建立一组方法,用于事件源调动事件听众。
9.2.3 JavaBean的开发工具简介

1 Borland公司的JBuilder
  使用JBuilder,开发者可以使用任何包括在这个产品中的或是从第三方供应商购买的JavaBean组件迅速地开发出应用程序,也可以使用JBuilder的可视化设计工具和wizard创建自己的可复用的JavaBean组件。JBuilder含有功能强大的JavaBean数据库组件,它可以满足创建与数据库有关的应用程序的需求。另外,JBuilder提供了Java优化工具集为专业Java开发者提供了综合的、高性能的开发解决方案。JBuilder的基于组件开发环境的几个主要子系统,包括组件设计器和双向工具引擎,都是使用JavaBean内置于Java中的。
   
关于JBuilder的更多信息,可以访问Borland公司的Web站点:
   
http://www.borland.com/jbuilder

 
2 IBM公司的Visual Age for Java
  IBM的Visual Age for Java的发布使得客户/服务器系统的Internet应用程序的实现成为现实。这个工具将Java的快速开发环境与可视化编程结合在一起。Visual Age for Java是一个创建可与Java兼容的应用程序、applet和JavaBean组件的编程环境,它使得开发者可以将注意力集中在应用程序的逻辑设计上。Visual Age for Java可以帮助开发者实现许多应用程序中经常需要的任务,如通讯代码、在企业级上进行Web连接以及用户接口代码的创建。
  
关于Visual Age for Java的更详细的信息可以查看Web站点:
  
http://www.software.ibm.com/ad/vajava

 
3 SunSoft公司的Java Studio
  Java Studio是一个可视化组装工具,一个"所见即所得"的HTML创作工具和一个完全使用Java编写的可重复使用的组件开发工具。Java Studio使用的JavaBean技术包含了一个丰富而强壮的商业组件集合,包括图表、曲线以及通过窗体和电子表格等支持的数据库访问和操作。此外,还包括用于创建网络软件辅助组件。辅助组件包括电子表格、白板和聊天组件。
  
Java Studio的web网址位于:
  
http://www.sun.com/studio/
9.2.4 使用BeanBox测试JavaBean

BDKBeans Developmen Kit)是Sun公司发布的Beans开发工具箱,它与JDK配合使用,可以生成使用Bean事件模型的BeansBDK的使用依赖于JDKBeanBoxBDK中自带的一个用于测试Beans的工具,可以用它可视地管理Beans的属性和事件。BeanBox并不是一个建立Beans的工具,它只是一个测试工具,我们可以通过它来了解Beans

9.3 RMI的基本概念和编程简介
9.3.1 RMI的基本概念

Java RMIRemote Method Invocation--Java的远程方法调用是Java所特有的分布式计算技术,它允许运行在一个Java虚拟机上的对象调用运行在另一个Java虚拟机上的对象的方法,从而使Java编程人员可以方便地在网络环境中作分布式计算。面向对象设计要求每个任务由最适合该任务的对象执行,RMI将这个概念更深入了一步,使任务可以在最适合该任务的机器上完成。

RMI定义了一组远程接口,可以用于生成远程对象。客户机可以象调用本地对象的方法一样用相同的语法调用远程对象。RMI API提供的类和方法可以处理所有访问远程方法的基础通信和参数引用要求的串行化。

远程方法调用类似于Sun公司1985年提出的远程过程调用(RPC)特征。RPC也要求串行化参数和返回数值数据,但由于没有涉及对象,情况比较简单。Sun开发了外部数据表示(XDR)系统,支持数据串行化。RPCRMI之间的一个重要差别是RPC用快速而不够可靠的UDP协议,RMI用低速而可靠的TCP/IP协议。
  远程方法调用(RMI)和CORBA都是分布式计算技术,在进行分布式时各有其优缺点,为了有助于了解RMI的特点和用途,有必要讨论一下CORBARMI的区别。
  CORBACommon Object Request Broker Architecture)是OMGObject Management Architecture(对象管理结构),它是面向对象的分布式系统建立所依据的标准。CORBA被设计成一个能供所有编程语言使用的一个开放性说明,就是说一个机器上的Java客户可以要求另一个用SmallTalkC++的机器服务。正是由于这种语言的独立性使得CORBA这么灵活和吸引人。为了适应语言独立性,CORBA采用了非常通用的标准作为其接口。在不同的语言中,远程调用、签名和对象的引入有各自不同的定义,所以CORBA必须尽可能的中立和开放。正是这种通用性是CORBA的一个弱点。当开发人员都采用CORBA时,他们要用一种新的标准定义语言接口,它要求开发者学习新的编程接口,从而减小了远程模型的透明性。
  RMI是为仅在JavaJava的分布式计算中而开发的。远程调用的标准是为了Java和应用Java的自然Java签名和调用而开发的,这使得RMIJava的开发者相当透明而且易于实现。RMIJava语言紧密集成从而同CORBA相比能够提供非常好的容错能力及对异常的处理。尽管JavaRMI标准不像CORBA那样语言独立,但Java本身是一个独立的平台,这就使RMI在跨平台的分布软件开发中是一个很好的选择。
  RMIJava语言在分布式计算上的基本模型,很多Java的分布式系统,包括我们本章要涉及的EJB,都是建立在RMI的思想上的。
9.3.2 RMI系统的一般结构

RMI系统包括3层,端头/框架层(Stubs/Skeletons)、远程应用层(Remote Reference Layer)和传送层(Transport,如图所示:

  客户机调用远程方法时,请求用客户机的端头调用。客户机引用端头作为远程机上对象的代表。上图所示的所有基础功能在客户机上都看不到。端头代码由rmic编译器长生,并用远程引用层(RRL)将方法调用请求传递到服务器对象。

9.3.3使用RMI构造分布式应用系统

RMI应用程序通常由两个独立的程序构成:一个server和一个client。一个典型的server应用程序创建一些远程对象,使它们可被引用,并等待客户端调用这些远程对象的方法。一个典型的client应用程序得到server上的一个或多个远程对象的远程引用,并调用这些对象的方法。RMI提供了serverclient通信和传递信息的机制。这样的应用程序叫做一个分布式对象应用程序。
  分布式对象应用程序需要定位远程对象:应用程序可以使用两种机制之一来获得远程对象的引用。应用程序可以使用RMI的命名工具rmiregistry来注册它的远程对象,或者象进行一般操作一样传递和返回远程对象的引用。
  和远程对象通信:远程对象之间的通信细节由RMI来处理。对程序员来说,远程通信就像一个标准的Java方法调用。
  装载被传递对象的类字节码:因为RMI允许调用者向远程对象传递对象,所以它提供了传递数据和装载一个对象代码的必要机制。
  下图描述了一个使用注册机制获得一个远程对象引用的RMI分布式应用程序。Server方调用注册器将一个远程对象和一个名字联系起来。Client方在Server

抱歉!评论已关闭.