Java远程方法调用(4)
· 代理
因为RMI答应使用Java实现下载属性,所以您可使用RMI 编写代理系统。代理的最简单格式如下:
import java.rmi.*;
public interface AgentServer extends Remote {
void accept(Agent agent)
throws RemoteException, InvalidAgentException;
}
public interface Agent extends java.io.Serializable {
void run();
}
启动一个代理也就创建了实现Agent (代理)接口、找到服务器、激活接受该代理对象的类。该代理的执行程序将被下载到服务器上运行。accept方法将启动一个该代理的新线程,激活其run方法,然后返回,从而使该代理一直执行到run方法返回为止。代理可通过激活在另一台主机上运行的服务程序的accept方法而移植到该主机,而其本身则作为将被接受的代理来传递,并结束其在原来主机上的线程。
面向对象的代码重用与设计模式
面向对象的编程是一项答应代码重用的强大技术。很多企业组织都使用面向对象的编程来减轻创建程序的负担和提高系统的灵活性。RMI是完全面向对象的--信息被发送给远程对象,而且对象可以被传递和返回。
Design Patterns (设计模式)目前在描述面向对象设计的实践活动中获得了相当大的成功。首先是因为Design Patterns 的创新工作而使之大受欢迎,这些编程方式是一种正式描述解决某类特定问题的完整方法的途径。所有这些设计模式都依靠于创建一个或多个抽象概念,这些抽象概念答应不同的实现,从而答应和增强软件重用。软件重用是面向对象技术的主要优势,而设计模式则是促进重用的最受欢迎的技术之一。
所有设计模式都依靠面向对象的多态性--这是对象( 如Task )拥有多个实现的能力。算法的普通部分(如compute 方法)不必知道使用了哪个实现,它只需知道得到一个对象后应该对该对象采取什么操作。非凡地,计算服务器就是Command (指令)模式的一个例子,它可使您将请求 (任务)表示为对象,并对其进行调度。
只有当包括执行程序在内的完整对象能在客户机和服务器之间传递时,才会存在这样的多态性。DCE和DCOM等传统的RPC系统以及CORBA等基于对象的RPC系统不能下载并执行程序,因为它们不能把真实对象作为参数传递,而只能传递数据。
RMI可传递包括执行程序在内的所有类型,所以您可以在分布式计算解决方案中,而不仅仅是本地计算中使用面向对象的编程--包括设计方式。假如没有RMI这样完全面向对象的系统,那么您就必须放弃很多分布式计算系统中的设计方式--以及面向对象的软件重用的其它形式。
· 与现有服务器的连接
人们常说,RMI主要是“从Java到Java”,但这种说法掩盖了这样一个事实:Java可使用被称为JNI的本机方法接口,很轻易地与现有和原有系统连接。JNI和RMI的混合使用与任何其它Java程序一样简单。您可使用JDBC,再结合RMI,与现有的关系数据库连接。也就是说,您可使用RMI连接二层次和三层次系统--即使双方都不是用Java 编写的亦可。这样做有很大的好处和优势,下面会具体阐述。但首先让我们看一看它是如何完成的。
假定您现在有一台在关系数据库中存储了有关客户订单信息的服务器。在任何多层次系统中,您都得设计一个远程接口,以便于客户机访问服务器--利用作为Remote 接口的RMI:
import java.rmi.*;
import java.sql.SQLException;
import java.util.Vector;
public interface OrderServer extends Remote {
Vector getUnpaid() throws RemoteException, SQLException;
void shutDown() throws RemoteException;
// ... other methods (getOrderNumber, getShipped, ...)
}
java.sql包包含JDBC包。每个远程方法均可被服务器采用实际数据库的JDBC调用,或通过采用其它数据库访问机制的本机方法实现。上面所示的方法返回一个Order (订单) 对象的Vector (列表)。Order (订单)就是在您的系统中定义的、用来保存客户订单的类。
本节将介绍如何使用JDBC实现getUnpaid,和如何使用JNI 实施shutDown。
· JDBC -- 连接数据库
使用JDBC实现getUnpaid的OrderServerImpl如下: