All things are difficult before they are easy. 没有软件的裸机是一具僵尸,没有硬件的软件是一个幽灵。2012,专注于Linux和C语言,关注自动化、性能测试,关注开源社区和开源测试工具、方法,尝试测试团队管理!
Java RMI 实例及实现方式总结
上一篇 /
下一篇 2010-11-09 21:34:46
/ 个人分类:Java
今天刚好对Java RMI进行了简单的学习,也写了一个实例,简单总结一下吧。1.RMI的基本体系结构RMI的基本体系结构,概括起来说,由三个抽象层组成: 1、存根/框架层(Stubs/Skeletons Layer)RMI为我们引入了两种特殊类型的对象,称为存根(Stub)和框架(Skeleton),它们组成了RMI的第一层。在远程通信的时候,要利用TCP/IP协议,做很多底层数据的打包传输。运用Java分布式计算技术,我们先要把数据或者对象转换成字节流 (byte stream),便于网络传输,这个过程叫汇集(marshaling);当收到远程传来的字节流后,我们要把流信息转换成对象或者数据,这个过程叫解读 (unmarshaling),它与汇集刚好相反。Stub和Skeleton层位于实际应用程序之下,建立在Proxy(代理)设计方案之上。Stub类的作用是远程服务器实现的代理的角色,Stub是客户方对象;Skeleton类用于帮助对象通过RMI链接与Stub通信,它从链路中读取方法调用的参数,向远程服务实现对象进行调用,接受返回值,然后再把返回值写回到Stub。 2、远程引用层(Remote Reference Layer)远程引用层定义和支持着RMI连接的调用语义(semantics)。RMI进行远程访问要用到JRMP(Java Remote Method Protocol,即Java远程方法协议),这一层提供专用于JRMP的RemoteRef对象,它位于java.rmi.server包内,代表着远程对象的一个句柄。RemoteRef使用远程引用来执行远程对象的一个远程方法调用。 3、传输层(Transport Layer)传输层在JVM之间建立基于流的网络连接,并且负责设置和管理这些连接。这时候,RMI使用一种线级(wire-level)协议进行基于TCP/IP的连接,该协议就是Java远程方法协议(JRMP,即Java Remote Method Protocol)。在JDK版本1.2开始,JRMP不再需要Skeleton,而是使用reflection来建立与远程服务的连接。为了生成Stub,我们须用rmic。当前的RMI实现中,传输层建立在TCP/IP基础上,设计用于在客户和服务器之间建立一条连接(即使联网有障碍)。2.RMI开发的基本步骤我们使用RMI编写Client/Server模式(客户/服务器)应用程序,包括6个基本步骤:1) 定义远程接口2) 实现远程接口3) 准备远程调用的服务器对象4) 生成残根Stub(客户代理)和框架Skeleton(服务器实体)5) 用rmiregistry找到远程对象6) 运行测试RMI分布式应用3.实现RMI的简单实例下面的一些代码时根据网上的资料修改并在本机运行通过的。另外,推荐另一个很简单的例子,就在wikipedia上的这个吧,这个example也非常不错的:http://en.wikipedia.org/wiki/Java_remote_method_invocation贴自己的RMI简单实例代码吧:import java.rmi.Remote; import java.rmi.RemoteException;
/** * @className: IHello * @description: 定义一个远程接口,必须继承Remote接口,其中需要远程调用的方法必须抛出RemoteException异常 * @author: 笑遍世界 * @createTime: 2010-11-9 下午12:33:21 */
public interface IHello extends Remote {
/** * 简单的返回“Hello World!"字样 * @return 返回“Hello World!"字样 * @throws java.rmi.RemoteException */ public String helloWorld() throws RemoteException;
/** * 一个简单的业务方法,根据传入的人名返回相应的问候语 * @param someBodyName 人名 * @return 返回相应的问候语 * @throws java.rmi.RemoteException */ public String sayHelloToSomeBody(String someBodyName) throws RemoteException; }
|
import java.rmi.RemoteException; import java.rmi.server.UnicastRemoteObject;
/** * @className: HelloImpl * @description: RIM远程接口的实现 * @author: 笑遍世界 * @createTime: 2010-11-9 下午12:35:47 */ public class HelloImpl extends UnicastRemoteObject implements IHello { /** * */ private static final long serialVersionUID = 1L;
/** * 因为UnicastRemoteObject的构造方法抛出了RemoteException异常,因此这里默认的构造方法必须写,必须声明抛出RemoteException异常 * * @throws RemoteException */ public HelloImpl() throws RemoteException { }
/** * 简单的返回“Hello World!"字样 * * @return 返回“Hello World!"字样 * @throws java.rmi.RemoteException */ public String helloWorld() throws RemoteException { return "Hello World!"; }
/** * 一个简单的业务方法,根据传入的人名返回相应的问候语 * * @param someBodyName 人名 * @return 返回相应的问候语 * @throws java.rmi.RemoteException */ public String sayHelloToSomeBody(String someBodyName) throws RemoteException { return "你好," + someBodyName + "!"; } }
|
import java.net.MalformedURLException; import java.rmi.AlreadyBoundException; import java.rmi.Naming; import java.rmi.RemoteException; import java.rmi.registry.LocateRegistry;
/** * @className: HelloServer * @description: 创建RMI注册表,启动RMI服务,并将远程对象注册到RMI注册表中。 * @author: 笑遍世界 * @createTime: 2010-11-9 下午12:41:39 * */
public class HelloServer { public static void main(String args[]) {
try { //创建一个远程对象 IHello rhello = new HelloImpl(); //本地主机上的远程对象注册表Registry的实例,并指定端口为8888,这一步必不可少(Java默认端口是1099),必不可缺的一步,缺少注册表创建,则无法绑定对象到远程注册表上 LocateRegistry.createRegistry(8888);
//把远程对象注册到RMI注册服务器上,并命名为RHello //绑定的URL标准格式为:rmi://host:port/name(其中协议名可以省略,下面两种写法都是正确的) Naming.bind("rmi://localhost:8888/RHello",rhello); // Naming.bind("//localhost:8888/RHello",rhello);
System.out.println(">>>>>INFO:远程IHello对象绑定成功!"); } catch (RemoteException e) { System.out.println("创建远程对象发生异常!"); e.printStackTrace(); } catch (AlreadyBoundException e) { System.out.println("发生重复绑定对象异常!"); e.printStackTrace(); } catch (MalformedURLException e) { System.out.println("发生URL畸形异常!"); e.printStackTrace(); } } }
|
import java.net.MalformedURLException; import java.rmi.Naming; import java.rmi.NotBoundException; import java.rmi.RemoteException;
/** * @className: HelloClient * @description: 客户端测试,在客户端调用远程对象上的远程方法,并返回结果。 * @author: 笑遍世界 * @createTime: 2010-11-9 下午01:27:02 */ public class HelloClient { public static void main(String args[]){ try { //在RMI服务注册表中查找名称为RHello的对象,并调用其上的方法 IHello rhello =(IHello) Naming.lookup("rmi://localhost:8888/RHello"); System.out.println(rhello.helloWorld()); System.out.println(rhello.sayHelloToSomeBody("笑遍世界")); } catch (NotBoundException e) { e.printStackTrace(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (RemoteException e) { e.printStackTrace(); } } }
|
参考资料:http://lavasoft.blog.51cto.com/62575/91679http://developer.51cto.com/art/200906/130417.htm
收藏
举报
TAG:
java
JAVA
Java
RMI