Java RMI(远程方法调用) 实例与分析 (转)

目的:

  通过本文,可以加深对Java RMI的理解,知道它的工作原理,怎么使用等. 也为了加深我自己的理解,故整理成文.不足之处,还望指出.

概念解释:

RMI(RemoteMethodInvocation):远程方法调用,顾名思义,通过远程的方式调用非本地对象的方法并返回结果。使用远程调用通常解决本地计算瓶颈问题,例如分布式记算,最近很火的阿尔法狗人机大战,据说运算使用上千个CPU。

JRMP(java remote method protocol):java远程方法协议,这是完成java到java远程调用的协议,基于TCP协议。

stub与skeleton:这两个概念下面会用到,这里解释下,skeleton是放在服务端的代理,它知道真正的对象在哪。stub是放在客户端的代理,它记录了查找和调用skeleton信息。理解成远程对象引用也成.

 

容易混淆的概念:

  远程方法调用与远程过程调用的区别:远程方法调用是java独有的,基于JRMP对象流协议实现,支持传输java序列化对象。远程过程调用是基于socket技术实现的,不能传输java对象,socket套接字协议支持多种语言。它们都是基于TCP协议传输。远程方法调用传输的是java序列化对象和基本数据类型,而远程过程调用不支持传输对象。

RMI调用模型:

从宏观看,想要远程调用需要做两件事情,1,服务端向本地对象注册表中注册能被调用的远程对象. 2,客户端向远程对象注册表请求远程对象的引用.

Java中RMI实现:

先通过一个例子了解Java中RMI是怎么用的,然后再根据代码分析源码是如何实现的.

1,先创建远程对象接口,继承自Remote(稍后源码中有分析为什么要有这个接口)

package remote.test;

import java.rmi.Remote;
import java.rmi.RemoteException;
/**
 * 远程接口,实现Remote
 * @author lxz
 *
 */
public interface IRemote extends Remote{

    public String show()throws RemoteException;//声明方法
}

2,接口实现,需要继承UnicastRemoteObject类,等会分析

package remote.test;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

/**
 * 远程接口实现,继承UnicastRemoteObject
 * @author lxz
 *
 */
public class RemoteImpl extends UnicastRemoteObject  implements IRemote{
    public RemoteImpl()throws RemoteException{}//构造方法
    public String show()throws RemoteException{//调用方法实现
        System.out.println("进入");
        System.out.println(this.toString());
        return "远程调用成功";
    }
}

3,服务端向本地端口1234对象注册表注册对象和它的名字

package remote.test;

import java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

/**
 *  服务端启动,创建端口上的对象注册列表,向对象注册表中注册远程调用对象
 * @author lxz
 *
 */
public class TestServer {
    public static void main(String[] args) throws MalformedURLException, RemoteException, AlreadyBoundException, InterruptedException {
        RemoteImpl r = new RemoteImpl();//创建远程对象
        Registry rr = LocateRegistry.createRegistry(1234); //创建1234端口上的对象注册表,如果已经创建了就用getRegistry方法获取
        rr.bind("testrmi", r);//向注册表中注册对象
        System.out.println(r.toString());
    }
}    

4,根据JDK API,以上远程服务就算搭建完毕了,下面通过客户端调用测试

package remote.test;

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;

/**
 * 客户端启动,获得远程的对象注册表中的对象引用
 * @author lxz
 *
 */
public class TestClient {

    public static void main(String[] args) throws MalformedURLException, RemoteException, NotBoundException {
        IRemote r = (IRemote) Naming.lookup("rmi://localhost:1234/testrmi");//获取远程1234端口对象注册表中testrmi的stub
        String a = r.show();//调用引用的方法,实际上调用的是stub,由stub与服务端交互并返回结果
        System.out.println(a);
    }
}

执行结果如下:

------------------------------------------

服务端:

RemoteImpl[UnicastServerRef [liveRef: [endpoint:[192.168.1.253:58169](local),objID:[-60651394:1539d5944e6:-7fff, -6910034932968554489]]]]
客户端:

远程调用成功
------------------------------------------

这样就完成了一个远程对象注册与远程对象方法调用的完整例子. 现在根据这个例子来分析它为什么要继承UnicastRemoteObject,实现Remote,向注册表注册等等.

首先远程对象实现类中需要继承UnicastRemoteObject类,UnicastRemoteObject具有注册为远程对象,生成远程引用的功能等,所有都已经被JDK封装好了,不需要编写,其中的实现有些是sun包开头的,不公开.

UnicastRemoteObject继承关系:

 

有了远程对象实现类,看服务端的启动逻辑,其中:

Registry rr = LocateRegistry.createRegistry(1234); 

LocateRegistry类:用于创建或获取某端口的对象注册表

LocateRegistry.createRegistry:这个方法表示获得远程对象注册表引用,返回Registry对象

Registry:真正操作远程对象注册表的接口

接着,

rr.bind("testrmi", r);

利用Registry的对象,把刚刚创建的远程对象注册为名称testrmi. 这里还有一种写法,效果是一样的.

LocateRegistry.createRegistry(1234); //创建,如果已经创建了就可省略这一句
Naming.bind("rmi://localhost:1234/testrmi", r);//需要带上端口

Naming:与对象注册表交互的工具类

上面是服务端从远程对象创建到对象注册的整个逻辑.客户端调用的逻辑比较简单,先通过Naming工具类获取到远程对象的引用以后,就可以正常使用了

(IRemote) Naming.lookup("rmi://localhost:1234/testrmi");

这里返回的"引用"和通常讲的对象引用不同,是远程对象的引用信息.拿到这个"引用"以后就可以像使用真正的对象一样调用其中的方法.

 

结束.

http://www.cnblogs.com/qinggege/p/5306852.html

 

时间: 2024-10-04 00:17:44

Java RMI(远程方法调用) 实例与分析 (转)的相关文章

Java的RMI远程方法调用实现和应用

最近在学习Dubbo,RMI是很重要的底层机制,RMI(Remote Method Invocation)远程方法调用是一种计算机之间利用远程对象互相调用实现双方通讯的一种通讯机制.使用这种机制,某一台计算机(即JVM虚拟机)上的对象可以调用另外一台计算机上的对象来获取远程数据. RMI的实现对建立分布式Java应用程序至关重要,是Java体系非常重要的底层技术. >>RMI的概念和原理 RMI思路是在客户端安装一个代理(proxy),代理是位于客户端虚拟机中的一个对象,对于客户端对象,看起来

关于java RMI分布式程序开发实例

关于java RMI分布式程序开发实例   作者: javaboy2012 Email:yanek@163.com qq:    1046011462   一. 服务器端     接口定义:注意必须继承Remote接口 package com.yanek.rmi.server; import java.rmi.Remote; import java.rmi.RemoteException; import java.util.List; public interface ChannelManage

Java RMI原理与使用

Java RMI 指的是远程方法调用 (Remote Method Invocation).它是一种机制,能够让在某个 Java 虚拟机上的对象调用另一个 Java 虚拟机中的对象上的方法. Java RMI概念 在Java中,只要一个类继承了java.rmi.Remote接口,即可成为存在于服务器端的远程对象,供客户端访问并提供一定的服务.JavaDoc描述:Remote 接口用于标识其方法可以从非本地虚拟机上调用的接口.任何远程对象都必须直接或间接实现此接口.只有在"远程接口"(扩

java RMI原理详解

[本文转载自java RMI原理详解] 定义 RMI(Remote Method Invocation)为远程方法调用,是允许运行在一个Java虚拟机的对象调用运行在另一个Java虚拟机上的对象的方法. 这两个虚拟机可以是运行在相同计算机上的不同进程中,也可以是运行在网络上的不同计算机中. Java RMI:Java远程方法调用,即Java RMI(Java Remote Method Invocation)是Java编程语言里,一种用于实现远程过程调用的应用程序编程接口.它使客户机上运行的程序

RMI远程方法调用讲解教程

RMI远程方法调用讲解教程 1.RMI概述 RMI(Remote Method Invocation) RMI是分布式对象软件包,它简化了在多台计算机上的JAVA应用之间的通信. 必须在jdk1.1以上 RMI用到的类 java.rmi.Remote 所有可以被远程调用的对象都必须实现该接口 java.rmi.server.UnicastRemoteObject 所有可以被远程调用的对象都必须扩展该类 什么是RMI 远程方法调用是一种计算机之间对象互相调用对方函数,启动对方进程的一 种机制,使用

Java互斥锁简单实例_java

本文实例讲述了Java互斥锁.分享给大家供大家参考.具体分析如下: 互斥锁,常常用于多个线程访问独占式资源,比如多个线程同时写一个文件,虽然互斥访问方式不够高效,但是对于一些应用场景却很有意义 //没有互斥锁的情况(可以自己跑跑看运行结果): public class LockDemo { // private static Object lock = new Object(); // static确保只有一把锁 private int i = 0; public void increaseI(

Java RMI 介绍

一.Java RMI 概览 Java RMI 指的是远程方法调用 (Remote Method Invocation).它是一种机制,能够让在某个 Java 虚拟机上的对象调用另一个 Java 虚拟机中的对象上的方法.所以,RMI相关对象必须运行在Java虚拟机中. 在Java中,只要一个类extends了java.rmi.Remote接口,即可成为存在于服务器端的远程对象,供客户端访问并提供一定的服务.JavaDoc描述:Remote 接口用于标识其方法可以从非本地虚拟机上调用的接口.任何远程

java EJB 与网络应用实例

java EJB 与网络应用实例 Bean Instance(Bean实例) 一个Bean Instance是Bean位于一个容器中的instantiation,如果把bean比作class,那么Bean Instance就是Java Object. Bean-managed persistence(Bean自己所管理的永续性BMP) 这个术语是用来描述Enterprise Java Bean如何来存储它们的state到数据库教程或者是其他的存储机制.容器将促使Bean呼叫Bean的EjbLoa

用JAVA开发CORBA应用实例

应用实例 文章摘要: 通用对象代理体系结构CORBA(Common Object Request Broker Architecture)是对象管理组织所定义的用来实现现今大量硬件.软件之间互操作的解决方案,CORBA也是迈向面向对象标准化和互操作的重要一步. -------------------------------------------------------------------------------- 正文: 用JAVA开发CORBA应用实例 通用对象代理体系结构CORBA(C