软件业一直是计算机产业的核心,计算机刚问世的时候,计算机软件基本处于缓慢发展时期,那时候使用的计算机软件语言是与硬件紧密相关的机器语言,随后出现了汇编语言。随着计算机日益介入到人们的生活中间,软件也相应的变得更加复杂。
于是以编程人员为中心的高级语言替代了计算机发展初期的低级语言,其中,50年代末和60年代初的FORTRAN语言的出现是一个变革,同时像BASIC和LISP这样的高级语言也相应的产生了,这些语言使得编程人员可以超脱于具体的硬件结构,使用更接近于实际问题领域的术语表达其设计思想。
但是另一方面,这种新出现的自由度使得不断复杂的应用程序需要有更加复杂的软件来实现。软件工业自由度和复杂性的增加,软件开发队伍也不断膨胀,成本也不断提高。软件工业也在不断的寻求成本低廉而又快速可靠的软件开发方法,所以在90年代末期,基于组件的软件开发的思想开始得到了普遍的重视和应用。
软件组件就是指可以进行独立分离、易于重复使用的软件部分。JavaBean就是一种基于Java平台的软件组件思想。JavaBean也是一种独立于平台和结构的应用程序编程接口(API)。JavaBean保留了其他软件组件的技术精华,并增加了被其他软件组件技术忽略的技术特性,使得它成为完整的软件组件解决方案的基础,并在可移植的Java平台上方便地用于网络世界中。
其实你可以把组件理解成为童年时玩的积木,而把用组件搭起来的软件则可以理解成为你用积木搭的形状各异的作品。这种比喻也许可以让你理解为什么用组件搭建应用程序会比其他方法制作应用程序更加稳定和快速。因为软件的组件是可重用的,所以它肯定是经过了很多应用程序的测试,所以当你用它的时候出错的概率肯定比你自己重新写一个同样功能的模块的出错概率小。而用组件搭建应用程序同时也会更快速,这很容易理解,就像你用积木搭一座桥比你自己用木头做一座桥要快一样。
JavaBean也是一个很成功的组件模型,如果你用过JBuilder,那么你肯定会受益于它所提供的许多方便的控件,而这些控件几乎都是JavaBean。其实你已经不知不觉的在使用JavaBean了,只是你一直没有注意到而已。
1. 编写Bean的源程序SimpleBean.java如下:
import java.awt.*;
import java.io.Serializable;
public class SimpleBean extends
Canvas implements Serializable
{
//该bean从java.awt.Canvas派生,
所以具有了Canvas的所有属性和方法
public SimpleBean(){
setSize(60,40);
//设置该bean的尺寸
setBackground(Color.red);
//设置该bean的背景颜色
}
}
SimpleBean从java.awt.Canvas组件派生,所以是一个可视化的bean,并且实现了java.io.Serializable接口,这个接口是所有Bean都必须实现的,因为SimpleBean具有Canvas的所有属性和方法,如背景色和组件尺寸等属性,并可以调用相应的方法设置这些属性。
2. 编译源程序:
javac SimpleBean.java产生字节码文件SimpleBean.class。
3. 编写制作(nmake)文件
这个nmake文件会编译这个SimpleBean组件并会产生一个JAR文件。将编写好的makefile文件存储为simpe.gmk(UNIX)或simple.mk(windows),并与你的SimpleBean.class放在同一个目录下,nmake文件清单如下:
#gmumake文件
CLASSFILES= SimpleBean.class
JARFILE= SimpleBean.jar
all: $(JARFILE)
# 创建一个带有适当说明文件
(manifest)的JAR文件
$(JARFILE): $(CLASSFILES)
$(DATAFILES)
echo "Name: SimpleBean.class"
manifest.tmp
echo "Java-Bean: True"
manifest.tmp
jar cfm $(JARFILE) manifest.tmp *.class
@/bin/rm manifest.tmp
# 编译源程序
%.class: %.java
export CLASSPATH; CLASSPATH=. ;
javac $<
#删除产生的中间文件
clean:
/bin/rm -f *.class
/bin/rm -f $(JARFILE)
# nmake 文件
CLASSFILES= simplebean.class
JARFILE= simplebean.jar
all: $(JARFILE)
# 创建一个带有适当说明文件
(manifest)的JAR文件
$(JARFILE): $(CLASSFILES)
$(DATAFILES)
jar cfm $(JARFILE)
<<manifest.tmp *.class
Name: SimpleBean.class
Java-Bean: True
<<
#将类打包,"Java-Bean:True"
可以使得类出现在ToolBox窗口中
.SUFFIXES: .java .class
{sunw\demo\simple}.java
{sunw\demo\simple}.class :
set CLASSPATH=.
javac $<
#清除中间文件
clean:
-del sunw\demo\simple\*.class
-del $(JARFILE)
4. 运行makefile文件
对于UNIX,运行gnumake simple.gmk
对于windows,运行nmake -f simple.mk
会在当前目录下创建一个JAR文件,这个JAR文件里包含了这个bean的信息。
我们完成了一个很典型的JavaBean,其实就是一个有一定特殊规则的Java类,它有一些特殊的地方比如要实现某些接口类,不过归根结底它还是一个Java类,它可以使用任何Java语言里提供的功能比如说继承于Canvas等。
而上面我们提供的makefile则可以作为模板,你以后要编写你自己的bean的makefile的时候只需要修改上面提供的makefile就可以了。
RMI定义了一组远程接口,可以用于生成远程对象。客户机可以象调用本地对象的方法一样用相同的语法调用远程对象。RMI API提供的类和方法可以处理所有访问远程方法的基础通信和参数引用要求的串行化。
远程方法调用类似于Sun公司1985年提出的远程过程调用(RPC)特征。RPC也要求串行化参数和返回数值数据,但由于没有涉及对象,情况比较简单。Sun开发了外部数据表示(XDR)系统,支持数据串行化。RPC和RMI之间的一个重要差别是RPC用快速而不够可靠的UDP协议,RMI用低速而可靠的TCP/IP协议。
远程方法调用(RMI)和CORBA都是分布式计算技术,在进行分布式时各有其优缺点,为了有助于了解RMI的特点和用途,有必要讨论一下CORBA和RMI的区别。
CORBA(Common Object Request Broker Architecture)是OMG的Object Management Architecture(对象管理结构),它是面向对象的分布式系统建立所依据的标准。CORBA被设计成一个能供所有编程语言使用的一个开放性说明,就是说一个机器上的Java客户可以要求另一个用SmallTalk或C++的机器服务。
正是由于这种语言的独立性使得CORBA这么灵活和吸引人。为了适应语言独立性,CORBA采用了非常通用的标准作为其接口。在不同的语言中,远程调用、签名和对象的引入有各自不同的定义,所以CORBA必须尽可能的中立和开放。正是这种通用性是CORBA的一个弱点。当开发人员都采用CORBA时,他们要用一种新的标准定义语言接口,它要求开发者学习新的编程接口,从而减小了远程模型的透明性。
RMI是为仅在Java对Java的分布式计算中而开发的。远程调用的标准是为了Java和应用Java的自然Java签名和调用而开发的,这使得RMI对Java的开发者相当透明而且易于实现。RMI用Java语言紧密集成从而同CORBA相比能够提供非常好的容错能力及对异常的处理。尽管Java的RMI标准不像CORBA那样语言独立,但Java本身是一个独立的平台,这就使RMI在跨平台的分布软件开发中是一个很好的选择。
RMI是Java语言在分布式计算上的基本模型,很多Java的分布式系统,包括我们本章要涉及的EJB,都是建立在RMI的思想上的。
传统的分布式应用程序都是基于Client/Server结构的,而近年来人们发现基于Client/Server结构的应用程序有很多缺点,比如:如果客户端的代码需要改变,那么所有机器上的客户端程序都要重新安装;如果某台机器有了不可修复的损坏,那么得去别的机器上重新安装客户端软件才能够使用。
而基于Browser/Server结构的应用程序就没有以上的缺点了,我们可以使用任何一台有浏览器的机器来工作,而因为所有的程序逻辑都在服务器端,所以服务器端的代码变动不需要作为客户端的浏览器再做任何工作。
由于Browser/Server结构的这些优势,近年来关于Browser/Server的程序开发模式有了很多的研究和实践。而因为Browser没有办法表示复杂的程序逻辑,所以在表示界面的Browser和存储介质数据库之间必须还有一层结构,这层结构负责表示复杂的程序逻辑。
这就是我们所说的服务器端构件,在Brower/Server结构中,我们的工作就是开发服务器端构件,但是开发服务器端构件是很麻烦的工作。因为服务器端构件必须接受很多客户端的请求,因此它必须具有多线程和事务处理等能力,而这些也成为服务器端构件开发的难点所在。