java rmi遠程方法調用實例

RMI的概念html

  RMI(Remote Method Invocation)遠程方法調用是一種計算機之間利用遠程對象互相調用實現雙方通信的一種通信機制。使用這種機制,某一臺計算機上的對象能夠調用另一臺計算機上的對象來獲取遠程數據。RMI是Enterprise JavaBeans的支柱,是創建分佈式Java應用程序的方便途徑。在過去,TCP/IP套接字通信是遠程通信的主要手段,但此開發方式沒有使用面向對象的方式實現開發,在開發一個如此的通信機制時每每令程序員感受到乏味,對此RPC(Remote Procedure Call)應運而生,它使程序員更容易地調用遠程程序,但在面對複雜的信息傳訊時,RPC依然未能很好的支持,並且RPC未能作到面向對象調用的開發模式。針對RPC服務遺留的問題,RMI出如今世人面前,它被設計成一種面向對象的通信方式,容許程序員使用遠程對象來實現通訊,而且支持多線程的服務,這是一次遠程通信的革命,爲遠程通訊開闢新的里程碑。java

  Java RMI 指的是遠程方法調用 (Remote Method Invocation)。它是一種機制,可以讓在某個 Java 虛擬機上的對象調用另外一個 Java 虛擬機中的對象上的方法。能夠用此方法調用的任何對象必須實現該遠程接口。程序員

RMI的開發步驟服務器

  1. 先建立遠程接口及聲明遠程方法,注意這是實現雙方通信的接口,須要繼承Remote
  2. 開發一個類來實現遠程接口及遠程方法,值得注意的是實現類須要繼承UnicastRemoteObject
  3. 經過javac命令編譯文件,經過java -server 命令註冊服務,啓動遠程對象
  4. 最後客戶端查找遠程對象,並調用遠程方法

 

實例源碼:多線程

首先爲服務創建一個Model層,注意由於此對象須要現實進行遠程傳輸,因此必須繼承Serializable分佈式

package com.blankjor.rmi;

import java.io.Serializable;

/**
 * @desc 傳輸持久層話數據對象,必須實現Serializable接口
 * @author Blankjor
 * @date 2017年5月30日 下午3:28:45
 */
public class EntityData implements Serializable {
    private static final long serialVersionUID = 1L;
    private int id;
    private String name;
    private String tel;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getTel() {
        return tel;
    }

    public void setTel(String tel) {
        this.tel = tel;
    }

}

建立遠程接口MyRemote,注意遠程接口必需要繼承Remoteide

package com.blankjor.rmi;

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

/**
 * @desc 遠程接口,實現Remote
 * @author Blankjor
 * @date 2017年5月30日 下午2:49:05
 */
public interface MyRemote extends Remote {
    EntityData sayHello() throws RemoteException;

}

創建MyRemoteImpl實現遠程接口MyRemote,注意此爲遠程對象實現類,須要繼承UnicastRemoteObject,UnicastRemoteObject實現了須要的遠程接口this

package com.blankjor.rmi;

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

/**
 * @desc 接口實現,爲了完成一些遠程的功能,藉助UnicastRemoteObject,自動實現
 * @author Blankjor
 * @date 2017年5月30日 下午2:50:39
 */
public class MyRemoteImpl extends UnicastRemoteObject implements MyRemote {

    /**
     * 必須實現,爲了拋出 RemoteException
     * 
     * @throws RemoteException
     */
    protected MyRemoteImpl() throws RemoteException {
    }

    @Override
    public EntityData sayHello() throws RemoteException {
        EntityData ed = new EntityData();
        ed.setId(1);
        ed.setName("lyc");
        ed.setTel("110");
        return ed;
    }

}

創建遠程服務端,並開啓後進行註冊spa

package com.blankjor.rmi;

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

/**
 * @desc 註冊遠程服務服務端
 * @author Blankjor
 * @date 2017年5月30日 下午2:54:26
 */
public class MyRemoteServer {
    public static void main(String[] args) {
        try {
            System.out.println("遠程服務正在啓動,等待調用...");
            // 實例化遠程服務對象
            MyRemote remote = new MyRemoteImpl();
            // 進行註冊綁定
            LocateRegistry.createRegistry(1234);
            Naming.rebind("rmi://localhost:1234/RemoteHello", remote);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

運行後結果:.net

 

客戶端進行遠程服務的訪問,調用

package com.blankjor.rmi;

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

/**
 * @desc 調用遠程服務的客戶端
 * @author Blankjor
 * @date 2017年5月30日 下午3:00:02
 */
public class MyRemoteClient {
    public static void main(String[] args) {
        try {
            // 尋找遠程服務
            MyRemote service = (MyRemote) Naming.lookup("rmi://localhost:1234/RemoteHello");
            // 調用遠程服務方法
            EntityData ed = service.sayHello();
            System.out.println("Welcome " + ed.getName());
        } catch (MalformedURLException | RemoteException | NotBoundException e) {
            e.printStackTrace();
        }
    }
}

 運行後結果:

 

總結:
  從上面的過程來看,RMI對服務器的IP地址和端口依賴很緊密,可是在開發的時候不知道未來的服務器IP和端口如何,可是客戶端程序依賴這個IP和端口。
這也是RMI的侷限性之一。這個問題有兩種解決途徑:一是經過DNS來解決,二是經過封裝將IP暴露到程序代碼以外。
  RMI的侷限性之二是RMI是Java語言的遠程調用,兩端的程序語言必須是Java實現,對於不一樣語言間的通信能夠考慮用Web Service或者公用對象請求代理體系(CORBA)來實現。

 參考:http://www.cnblogs.com/leslies2/archive/2011/05/20/2051844.html

    http://lavasoft.blog.51cto.com/62575/91679/

相關文章
相關標籤/搜索