zoukankan      html  css  js  c++  java
  • Java远程方法调用(Remote Method Invocation,RMI)

    Java RMI简介:

    它是Java的一个核心API和类库,允许一个Java虚拟机上运行的Java程序调用不同虚拟机上运行的对象中的方法,即使这两个虚拟机运行于物理隔离的不同主机上。

    Java RMI在JDK1.1版本已经存在,是非常重要的底层技术。

    下面通过一个简单的例子来测试:

     1 package com.tc.remote;
     2 
     3 import java.rmi.Remote;
     4 import java.rmi.RemoteException;
     5 
     6 /**
     7  * 一个远程调用接口RMIQueryStatus
     8  * 远程接口必须声明为public
     9  * 远程接口必须继承自java.rmi.Remote
    10  */
    11 public interface RMIQueryStatus extends Remote{
    12 
    13     // 远程调用中的方法必须抛出RemoteException异常 
    14     RMIFileStatus getFileStatus(String filename) throws RemoteException;
    15 
    16 }
     1 package com.tc.remote;
     2 
     3 import java.io.Serializable;
     4 
     5 /**
     6  * RMI文件状态类,远程调用方法返回的对象
     7  */
     8 public class RMIFileStatus implements Serializable{
     9 
    10     private String filename;
    11 
    12     public RMIFileStatus() {
    13     }
    14 
    15     public RMIFileStatus(String filename) {
    16         this.filename = filename;
    17     }
    18 
    19     @Override
    20     public String toString() {
    21         return "RMIFileStatus{" +
    22                 "filename='" + filename + '\'' +
    23                 '}';
    24     }
    25 
    26 }
     1 package com.tc.remote;
     2 
     3 import java.rmi.RemoteException;
     4 import java.rmi.server.UnicastRemoteObject;
     5 
     6 /**
     7  * 远程接口的实现 .
     8  */
     9 public class RMIQueryStatusImpl extends UnicastRemoteObject implements RMIQueryStatus {
    10 
    11     /**
    12      * 因为UnicastRemoteObject的构造函数抛出了RemoteException异常
    13      * 这里默认构造方法必须写
    14      * @throws RemoteException
    15      */
    16     public RMIQueryStatusImpl() throws RemoteException {
    17     }
    18 
    19     @Override
    20     public RMIFileStatus getFileStatus(String filename) throws RemoteException {
    21         RMIFileStatus status = new RMIFileStatus(filename);
    22         // ...进行处理
    23         return status;
    24     }
    25 
    26 }
     1 package com.tc.remote;
     2 
     3 import java.net.MalformedURLException;
     4 import java.rmi.Naming;
     5 import java.rmi.RemoteException;
     6 import java.rmi.registry.LocateRegistry;
     7 
     8 /**
     9  * 创建RMI注册表,启动RMI服务,并将远程对象注册到RMI注册表中。
    10  */
    11 public class RMIQueryStatusServer {
    12 
    13     public static String RMI_URL = "rmi://localhost:8888/RHello";
    14 
    15     public static void main(String[] args) {
    16         try {
    17             RMIQueryStatusImpl queryStatus = new RMIQueryStatusImpl();
    18             // 注册表创建
    19             LocateRegistry.createRegistry(8888);
    20             // 绑定远端对象到名字
    21             Naming.rebind(RMI_URL,queryStatus);
    22 //            Naming.bind(RMI_URL,queryStatus);
    23 //            bind方法在已经为一个名字绑定一个对象,再向此名称绑定对象,会抛出异常
    24 //            而使用rebind方法不会
    25             System.out.println(">>>>>INFO:远程RMIQueryStatus对象绑定成功!");
    26         } catch (RemoteException e) {
    27             e.printStackTrace();
    28         } catch (MalformedURLException e) {
    29             e.printStackTrace();
    30         }
    31     }
    32 
    33 }
     1 package com.tc.remote;
     2 
     3 import java.net.MalformedURLException;
     4 import java.rmi.Naming;
     5 import java.rmi.NotBoundException;
     6 import java.rmi.RemoteException;
     7 
     8 /**
     9  * 客户端测试,在客户端调用远程对象上的远程方法,并返回结果。
    10  */
    11 public class RMIQueryStatusClient {
    12 
    13     public static void main(String[] args) {
    14         try {
    15             RMIQueryStatus queryStatus = (RMIQueryStatus) Naming.lookup(RMIQueryStatusServer.RMI_URL);
    16             // 调用远程方法,该调用如同调用本地方法
    17             RMIFileStatus status = queryStatus.getFileStatus("爆炸");
    18             System.out.println(status);
    19         } catch (NotBoundException e) {
    20             e.printStackTrace();
    21         } catch (MalformedURLException e) {
    22             e.printStackTrace();
    23         } catch (RemoteException e) {
    24             e.printStackTrace();
    25         }
    26     }
    27 
    28 }

    先运行RMIQueryStatusServer 的main方法:

    注意:虽然main方法的执行很快,但是服务器还是会继续运行的,红色的方块表示了运行。

    再运行RMIQueryStatusClient 的main方法:

    这里只是简单的进行了测试,感觉Client需要拿到Server的RMI_URL,还是有比较强的依赖性。

    希望实际项目中用到以后能够有更深刻的理解。

    http://docs.oracle.com/javase/8/docs/technotes/guides/rmi/index.html

    欢迎关注云原生玩码部落(https://www.funnycode.org.cn)
  • 相关阅读:
    c#之线程池优先级
    c#之线程池
    c# 回调委托
    c# Beginlnvoke 委托
    Qrcode生成二维码支持中文,带图片,带文字
    http://fonts.googleapis.com/css?打开很慢解决方案
    MVC多语言应用
    SQL参数化查询的问题
    MVC:从客户端中检测到有潜在危险的 Request.Form 值 的解决方法
    CSS计数器妙用
  • 原文地址:https://www.cnblogs.com/tiecheng/p/5892942.html
Copyright © 2011-2022 走看看