服务热线:13616026886

技术文档 欢迎使用技术文档,我们为你提供从新手到专业开发者的所有资源,你也可以通过它日益精进

位置:首页 > 技术文档 > JAVA > 新手入门 > 基础入门 > 查看文档

java远程方法调用(4)


  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如下:

import java.rmi.*;
import java.rmi.server.*;
import java.sql.*;
import java.util.vector;
public class orderserverimpl
extends unicastremoteobject
implements orderserver
{
connection db; // connection to the db
preparedstatement unpaidquery; // unpaid order query
orderserverimpl() throws remoteexception, sqlexception {
db = drivermanager.getconnection("jdbc:odbc:orders");
unpaidquery = db.preparedstatement("…");
}
public vector getunpaid() throws sqlexception {
resultset results = unpaidquery.executequery();
vector list = new vector();
while (results.next())
list.addelement(new order(results));
return list;
}
public native void shutdown();
}
其中大多是jdbc任务。除了以order开始的类型是您的系统的一部分类型以外,您所看到的所有类型均为jdbc或 rmi的一部分。构造函数初始化orderserverimpl对象,创建与jdbc url中所规定的数据库的连接( connection)。有了这个连接,我们就可以使用preparestatement定义一个能找到所有未付款订单的查询。在此还可为其它方法定义其它查询。orderserverimpl作为数据库在同一个系统上运行,而且还可能是在同一个进程中(下面将讨论shutdown)。
当getunpaid方法在rmi服务器对象orderserverimpl上被调用后,就会执行预先编译的查询,并返回包含所有匹配元素的jdbc resultset对象。随后,我们为结果集中的每个项目创建新的order对象,并将其添加到vector对象中( java 的动态数组)。在结束读取结果后,我们将这个向量返回给客户机,后者可将结果显示给用户,或者其他相关的人。

(未完待续)

扫描关注微信公众号