`
小嘴冰凉
  • 浏览: 457189 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

RMI实用教程

    博客分类:
  • j2se
阅读更多
   Java Remote Method Invocation ( RMI -- Java远程方法调用)允许您使用Java编写分布式对象。本文将介绍RMI的优点以及如何将其连接到现有的和原有的系统中,以及与用Java 编写的组件的连接,同时给出了一个详细的例子,可以给初学者提供一个学习范本。   

一、RMI(远程方法调用)的组成

      一个正常工作的RMI系统由下面几个部分组成: 

      1、远程服务的接口定义 
      2、远程服务接口的具体实现 
      3、桩(Stub)和框架(Skeleton)文件 
      4、一个运行远程服务的服务器 
      5、一个RMI命名服务,它允许客户端去发现这个远程服务 
      6、类文件的提供者(一个HTTP或者FTP服务器) 
      7、一个需要这个远程服务的客户端程序 


二、RMI(远程方法调用)的工作原理 

RMI系统结构,在客户端和服务器端都有几层结构。 
--------- ---------- 
| 客户 | | 服务器| 
---------- ---------- 
| | 
------------- ---------- 
| 占位程序 | | 骨干网 | 
-------------- ----------- 
| | 
------------------------------------ 
| 远 程 引 用 层 | 
------------------------------------ 
| | 
------------------------------------ 
| 传 输 层 | 
------------------------------------ 

     方法调用从客户对象经占位程序(Stub)、远程引用层(Remote Reference Layer)和传输层(Transport Layer)向下,传递给主机,然后再次经传 输层,向上穿过远程调用层和骨干网(Skeleton),到达服务器对象。 占位程序扮演着远程服务器对象的代理的角色,使该对象可被客户激活。 远程引用层处理语义、管理单一或多重对象的通信,决定调用是应发往一个服务器还是多个。传输层管理实际的连接,并且追追踪可以接受方法调用的远程对象。服务器端的骨干网完成对服务器对象实际的方法调用,并获取返回值。返回值向下经远程引用层、服务器端的传输层传递回客户端,再向上经传输层和远程调用层返回。最后,占位程序获得返回值。 

      要完成以上步骤需要有以下几个步骤: 

      1、生成一个远程接口 
      2、实现远程对象(服务器端程序) 
      3、编写服务器程序 、注册远程对象、启动远程对象
      4、编写客户程序 
在JDK1.5之后,用java提供的API将会更加的简单,可以参照下面的例子;

三、例子

1、远程接口

接口名:com.liuxiang.rmi.download.IRMI

该接口定义了一个方法,用于提供远程服务;

/**
 * 
 */
package com.liuxiang.rmi.download;

import java.rmi.Remote;
import java.rmi.RemoteException;

/**
 * 远程对象接口
 * @author liuxiang
 * 2007-8-30 下午09:39:15    
 *
 */
public interface IRMI extends Remote{
    public Object invoke(ITask task) throws RemoteException;
}

2、实现远程对象(服务器端程序)

类名:com.liuxiang.rmi.download.IRMIImpl

实现了远程接口定义的方法;该实现远程对象中,调用了传入参数的task.doWork()方法,同时执行一个本地调用,调用一个播放Mp3的代码段ProcessCaller.callMp3();

/**
 * 
 */
package com.liuxiang.rmi.download;

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

import com.liuxiang.callwindow.ProcessCaller;

/**
 * 远程对象的实现
 * @author liuxiang
 * 2007-8-30 下午09:41:32    
 *
 */
public class IRMIImpl extends UnicastRemoteObject implements IRMI {

    protected IRMIImpl() throws RemoteException {
        super();
    }

    /**
     * 
     */
    private static final long serialVersionUID = 6131922116577454476L;

    /* (non-Javadoc)
     * @see com.liuxiang.rmi.download.IRMI#invoke(com.liuxiang.rmi.download.ITask)
     */
    public Object invoke(ITask task) throws RemoteException {
        System.out.println("注意:这是一个远程调用");
        Object obj = task.doWork();
        System.out.println("调用ITask.doWork()方法的返回值:"+obj.toString());
        //客户端调用,可以在服务器端播放需要的音乐
        ProcessCaller.callMp3();
        return obj;
    }

}

3、播放Mp3代码段的源代码如下:

/**
 * 
 */
package com.liuxiang.callwindow;

/**
 * 在java中调用windows程序
 * @author liuxiang 2007-8-30 下午10:26:20
 * 
 */
public class ProcessCaller {
    /**
     * 调用Windows程序
     * 利用Windows Media Player播放mp3音乐
     */
    public static void callMp3() {
        Runtime ru = Runtime.getRuntime();
        try {
            // 调用播放器文件播放指定MP3
            Process p1 = ru
                    .exec("C:\Program Files\Windows Media Player\wmplayer F:/music/lx/刘若英-后来.mp3");
        } catch (Exception e) {

        }
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        callMp3();
    }

}

4、任务接口

该接口定义了远程方法需要传递的参数

/**
 * 
 */
package com.liuxiang.rmi.download;

import java.io.Serializable;

/**
 * 任务接口
 * @author liuxiang
 * 2007-8-30 下午09:35:53    
 *
 */
public interface ITask extends Serializable{
    public Object doWork();
}

5、任务接口实现

该实现定义了远程方法需要传递的参数

package com.liuxiang.rmi.download;

/**
 * 任务实现类
 * @author liuxiang
 * 2007-8-31 上午09:08:57    
 *
 */
public class TaskImpl implements ITask{

    public Object doWork() {
        System.out.println("当前程序处于远程调用中");
        return "动态上载对象的返回值";
    }
    
}

6、编写服务器程序 、注册远程对象、启动远程对象

代码:远程对象的注册类 该类应该在服务器端执行 执行之后, 该机器将变为RMI服务器 客户端可以通过正确的url来访问;服务器上的远程对象;执行对外报露的方法

/**
 * 
 */
package com.liuxiang.rmi.download;

import java.rmi.Naming;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

/**
 * 远程对象的注册类 该类应该在服务器端执行 执行之后,
 * 该机器将变为RMI服务器 客户端可以通过正确的url来访问
 * 服务器上的远程对象;执行对外报露的方法
 * 
 * @author liuxiang 2007-8-30 下午09:44:54
 * 
 */
public class RMIServer {
    /**
     * 如果没有创建一个Registry,Naming是不会帮助你创建的。 还是自己手工创建的比较的好
     * 
     * 尽量用下面的自己封装的bind方法来注册远程对象
     * 
     * @throws Exception
     */
    public static void registRemoteObject() throws Exception {
        IRMIImpl impl = new IRMIImpl();
        Naming.rebind("rmi://219.233.8.97:1111/mytask", impl);
        System.out.println("bound success!");
    }

    /**
     * 创建一个Registry对象
     * 
     * @return 返回一个Registry对象
     */
    private static Registry createRegistry() {
        Registry registry = null;
        int port = 1111;
        try {
            registry = LocateRegistry.getRegistry(port);
            registry.list();
            System.out.println("Register the exist server!");
        } catch (final Exception e) {
            try {
                registry = LocateRegistry.createRegistry(port);
                System.out.println("Register the exist server!port=" + port);
            } catch (final Exception ee) {
                ee.printStackTrace();
            }
        }
        return registry;
    }

    /**
     * 将对象注册到rmi服务器上
     */
    public static void bind() {
        Registry registry = null;
        registry = createRegistry();
        try {
            IRMIImpl impl = new IRMIImpl();
            registry.rebind("mytask", impl);
            System.out.println("mytask server start!");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        try {
            bind();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

运行该服务端代码后,将会注册一个远程服务对象,通过恰当的URL可以访问远程对象中的方法;运行后的结果如下:

Register the exist server!port=1111
mytask server start!
7、编写客户程序

代码首先获取一个远程对象,然后如同本地调用一样,调用远程对象中的方法。

/**
 * 
 */
package com.liuxiang.rmi.download;

import java.rmi.Naming;

/**
 * @author liuxiang
 * 2007-8-30 下午09:47:41    
 *
 */
public class RMIClient {
    /**
     * 调用远程对象中的方法
     * @throws Exception
     */
    public static void getRemoteObject() throws Exception{
        IRMI obj = (IRMI)Naming.lookup("rmi://localhost:1111/mytask");    //得到远程发布的服务
        TaskImpl task = new TaskImpl();
        Object result = obj.invoke(task);    //调用远程服务的方法
        System.out.println(result.toString());
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        try {
            getRemoteObject();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

最后,运行客户端代码,可以看到控制台分别输出了如下的内容:

Server端输出了更多的内容,如下:

Register the exist server!port=1111
mytask server start!
注意:这是一个远程调用
当前程序处于远程调用中
调用ITask.doWork()方法的返回值:动态上载对象的返回值
同时可以看到,会调用了Windows的Mediaplay播放本地磁盘的Mp3歌曲;

Client端输入了如下内容:

动态上载对象的返回值

四、RMI介绍

RMI(Remote Method Invocation,远程方法调用)是用Java在JDK1.1中实现的,它大大增强了Java开发分布式应用的能力。Java作为一种风靡一时的网络开发语言,其巨大的威力就体现在它强大的开发分布式网络应用的能力上,而RMI就是开发百分之百纯Java的网络分布式应用系统的核心解决方案之一。其实它可以被看作是RPC的Java版本。但是传统RPC并不能很好地应用于分布式对象系统。而Java RMI 则支持存储于不同地址空间的程序级对象之间彼此进行通信,实现远程对象之间的无缝远程调用。  

RMI目前使用Java远程消息交换协议JRMP(Java Remote Messaging Protocol)进行通信。JRMP是专为Java的远程对象制定的协议。因此,Java RMI具有Java的"Write Once,Run Anywhere"的优点,是分布式应用系统的百分之百纯Java解决方案。用Java RMI开发的应用系统可以部署在任何支持JRE(Java Run Environment Java,运行环境)的平台上。但由于JRMP是专为Java对象制定的,因此,RMI对于用非Java语言开发的应用系统的支持不足。不能与用非Java语言书写的对象进行通信。 

RMI为采用Java对象的分布式计算提供了简单而直接的途径。这些对象可以是新的Java对象,也可以是围绕现有API的简单的Java包装程序。Java体现了“编写一次就能在任何地方运行的模式。而RMI可将Java模式进行扩展,使之可在任何地方运行”。 

  因为RMI是以Java为核心的,所以,它将Java的安全性和可移植性等强大功能带给了分布式计算。您可将代理和梢?务逻辑等属性移动到网络中最合适的地方。如果您要扩展Java在系统中的使用,RMI将使您充分利用其强大功能。 

  RMI可利用标准Java本机方法接口JNI与现有的和原有的系统相连接。RMI还可利用标准JDBC包与现有的关系数据库连接。RMI/JNI和RMI/JDBC相结合,可帮助您利用RMI与目前使用非Java语言的现有服务器进行通信,而且在您需要时可扩展Java在这些服务器上的使用。RMI可帮助您在扩展使用时充分利用Java的强大功能。

 可以自由的传播本文,但必须注明出处!!



http://blog.csdn.net/juxtapose/archive/2007/09/30/1808468.aspx
分享到:
评论
1 楼 ytu_wu 2010-07-14  
很好,受益匪浅

相关推荐

    rmi设置

    【标签】"源码"和"工具"暗示这篇博文中可能包含了源代码示例以及使用RMI的实用工具或技巧。源码部分可能包括上述的远程接口、实现类以及客户端调用的示例。而“工具”可能指的是使用Java的RMI工具类,如`rmic`用于...

    《JSP应用教程》习题答案.doc

    ### JSP应用教程知识点解析 #### 一、B/S架构及其编程语言 **B/S架构特点及编程语言:** B/S架构(Browser/Server架构)是一种客户端通过浏览器访问服务器的应用模式,与传统的C/S(Client/Server)架构相比,B/S...

    Java2实用教程第4版-第13章-Java网络编程.ppt

    在Java2实用教程第4版的第13章中,主要讲解了以下几个核心知识点: 1. **URL类**:URL(Uniform Resource Locator)是互联网上资源的唯一标识。`URL`类在`java.net`包中,提供了构造和解析URL的功能。它通常由三...

    EJB教程

    EJB可以通过JNDI(Java Naming and Directory Interface)查找服务,通过RMI(Remote Method Invocation)进行远程调用。 **EJB的版本发展** EJB经历了多个版本的演进: 1. **EJB 1.x**:早期版本,接口复杂,...

    XLR Processor Family Programming Reference Manual

    综上所述,《XLR处理器家族编程参考手册》是一本全面而深入的教程,它为开发者提供了掌握XLR732芯片所需的一切信息。通过深入研读并实践其中的内容,开发者可以充分利用XLR732的性能,开发出高效、可靠的系统。

    jmeter详细使用教程

    **JMeter详细使用教程** Apache JMeter是一款强大的性能测试工具,广泛用于Web应用的压力测试、负载测试和功能测试。它完全免费,且基于Java,具备跨平台性,适合各种类型的性能测试需求。以下是对JMeter各项功能的...

    【中文】【EJB实例全教程】【(CHM)】

    根据提供的文件信息,我们可以推断出这是一本...综上所述,《EJB实例全教程》这本书不仅涵盖了EJB的基础概念和技术细节,还提供了大量实用的示例代码,对于想要深入了解EJB技术的开发者来说是一本非常有价值的参考书。

    java基础教程

    基础类库包括java.lang、java.util、java.io等包,它们分别涉及语言基础、实用工具类和输入输出功能。 4. Java软件开发技术: 这部分内容会涉及Java开发中的各种技术,包括但不限于JDBC(Java数据库连接),用于...

    Java 2 高级程序设计百事通.pdf

    总的来说,《Java 2 高级程序设计百事通》是一本深度和广度兼具的Java教程,它不仅教你如何使用这些高级技术,更教会你如何将它们融入实际项目,提升你的编程能力。无论是为了个人提升,还是作为教学材料,这本书都...

    JAVA学习笔记(林信良 编著 教程)

    ### JAVA学习笔记(林信良 编著 教程) #### 重要知识点解析 **一、Java概述** 1. **起源与发展:** - Java 最初由 Sun Microsystems 的 James Gosling 在 Green Project 中开发,其最初的命名灵感来源于 ...

    Java语言程序设计教程-雷学生-电子教案-2041

    Java语言程序设计教程深入解析 Java作为一种广泛应用的编程语言,其强大的工具包和类库是其强大功能的基础。本章将聚焦于Java中的一些常用工具包和类,这对于理解和提升Java编程技能至关重要。 11.1 Java常用工具...

    hibernate3.6-jar包

    在【描述】中提到的博文链接指向了iteye博客的一个条目(虽然具体内容未给出),这通常会包含关于如何使用Hibernate 3.6的教程、最佳实践或者常见问题的解答。通过访问该链接,开发者可以获取更深入的使用指南和示例...

    Fundamental Networking in Java

    本书《基础网络编程在Java》是一本非常实用的教程,不仅适合初学者入门学习,也适合有一定基础的开发人员进一步提升自己的技能。通过阅读本书,读者可以系统地掌握Java网络编程的基本概念和技术细节,为后续的项目...

    Spring 3.x企业应用开发实战(高清版)-6

    总的来说,《Spring 3.x企业应用开发实战(高清版)》是一本全面而实用的Spring教程,无论你是初学者还是有经验的开发者,都能从中受益匪浅,提升自己的Spring技能,为企业的应用开发打下坚实基础。通过阅读这本书,...

    JFoenix:JavaFX材料设计库

    JFoenix是一个开源Java库,它使用Java组件实现Google Material Design JFoenix for Java 9- (9.xx) JFoenix for Java 8- (8.xx) 适用于Android的JFoenix- 可从获得已发布的版本 ...具有RMI技术的车辆预订系

    JAVA_Thinking in Java(中文版 由yyc,spirit整理).chm

    本教程由yyc,spirit整理 ------------------------------------------------- “Thinking in Java”详细目录   写在前面的话 引言 1. 前提 2. Java的学习 3. 目标 4. 联机文档 5. 章节 6. 练习 7. 多媒体CD...

    JBuilder开发人员指南

    《JBuilder开发人员指南》是一本专为Java开发者设计的实用教程,主要涵盖了数据库应用程序的开发、分布式应用程序的构建以及如何创建和使用JavaBean。JBuilder是Borland公司推出的一款强大的Java集成开发环境(IDE)...

Global site tag (gtag.js) - Google Analytics