搜尋
首頁JavaJava基礎Java RMI圖文詳解(附範例)

Java RMI圖文詳解(附範例)

Dec 24, 2019 pm 05:33 PM
java

Java RMI圖文詳解(附範例)

Java RMI:Java遠端方法調用,即Java RMI(Java Remote Method Invocation)是Java程式語言裡,一種用於實現遠端過程調用的應用程式介面。

它使客戶機上運行的程式可以呼叫遠端伺服器上的物件。遠端方法呼叫特性使Java程式設計人員能夠在網路環境中分佈操作。 RMI全部的宗旨就是盡可能簡化遠端介面物件的使用。

我們知道遠端過程呼叫(Remote Procedure Call, RPC)可以用於一個進程呼叫另一個進程(很可能在另一個遠端主機上)中的過程,從而提供了過程的分佈能力。 Java 的 RMI 則在 RPC 的基礎上向前又邁進了一步,即提供分散式物件間的通訊。

RMI(Remote Method Invocation)為遠端方法調用,是允許運行在一個Java虛擬機的物件調用運行在另一個Java虛擬機器上的物件的方法。

這兩台虛擬機器可以是運作在相同電腦上的不同流程中,也可以是運作在網路上的不同電腦中。

【JavaRMI】

一、工作原理

RMI能讓一個Java程式去呼叫網路中另一台電腦的Java物件的方法,那麼呼叫的效果就像是在本機上呼叫一樣。通俗的講:A機器上面有一個class,透過遠端調用,B機器調用這個class 中的方法。

RMI,遠端方法呼叫(Remote Method Invocation)是Enterprise JavaBeans的支柱,是建立分散式Java應用程式的方便途徑。 RMI是非常容易使用的,但它非常的強大。

RMI的基礎是接口,RMI架構基於一個重要的原理:定義接口和定義接口的具體實現是分開的。下面我們透過具體的例子,建立一個簡單的遠端運算服務和使用它的客戶程式

二、RMI包含部分:

1、遠端服務的接口定義

2、遠端服務介面的具體實作

3、樁(Stub)和框架(Skeleton)檔案

4、一個運行遠端服務的伺服器

5、一個RMI命名服務,它允許客戶端去發現這個遠端服務

6、類別檔案的提供者(一個HTTP或FTP伺服器)

7、一個需要這個遠端服務的客戶端程式

三、RMI的用途?

#RMI的用途是為分散式Java應用程式之間的遠端通訊提供服務,提供分佈式服務。

目前主要應用時封裝在各個J2EE專案框架中,例如Spring,EJB(Spring和EJB均封裝了RMI技術)

在Spring中實作RMI:

①在伺服器端定義服務的接口,定義特定的類別實作這些接口;

②在伺服器端使用org.springframework.remoting.rmi.RmiServiceExporter類別來註冊服務;

③在客戶端使用org.springframework.remoting.rmi.RmiProxyFactoryBean來實作遠端服務的代理功能;

④在客戶端定義存取與伺服器端服務介面相同的類別

# 、RMI的局限?                                         

RMI目前使用Java遠端訊息交換協定JRMP(Java Remote Messaging Protocol)進行通訊。 JRMP是專為Java的遠端物件製定的協議,由於JRMP是專為Java物件製定的,因此,RMI對於使用非Java語言開發的應用系統的支援不足。

不能與用非Java語言書寫的物件通訊(意思是只支援客戶端和伺服器端都是Java程式的程式碼的遠端呼叫)。

五、RMI的使用限制?

由於客戶機和伺服器都是使用Java編寫的,二者平台相容性的要求只是雙方都運作在版本相容的Java虛擬機器上。

六、RMI呼叫遠端方法的參數和傳回值

當呼叫遠端物件上的方法時,客戶機除了可以將原始類型的資料作為參數一外,還可以將對像作為參數來傳遞,與之相對應的是返回值,可以返回原始類型或對象,這些都是透過Java的對象序列化(serialization)技術來實現的。 (換而言之:參數或傳回值如果是物件的話必須實作Serializable介面)

#七、 RMI應用程式的基本模型

Java RMI圖文詳解(附範例)

Java RMI圖文詳解(附範例)

######################### #######八、RMI體系結構###################樁/框架(Stub/Skeleton)層:客戶端的樁和伺服器端的框架;## #

遠端引用(remote reference)層:處理遠端引用行為

傳送層(transport):連線的建立與管理,以及遠端物件的追蹤

九、 RMI類別和介面(完成一個簡單RMI需要用到的類別)。

Java RMI圖文詳解(附範例)

(一) Remote介面:是一個不定義方法的標記介面

Public interface Remote{}

#在RMI中,遠端介面宣告了可以從遠端Java虛擬機器呼叫的方法集。遠端介面符合下列要求:

1、遠端介面必須直接或間接擴充Java.rmi.Remote接口,且必須宣告為public,除非客戶端於遠端介面在同一包中

2.在遠端介面中的方法在宣告時,除了要拋出與應用程式有關的一場之外,還必須包括RemoteException(或它的超類,IOExcepion或Exception)異常

#3、在遠端方法聲明中,作為參數或傳回值聲明的遠端物件必須聲明為遠端接口,而非該介面的實作類別。

(二) RemoteObject抽象類別實作了Remote介面和序列化Serializable接口,它和它的子類別提供RMI伺服器函數。

(三) LocateRegistry final()類別用於取得特定主機的引導遠端物件註冊伺服器程式的參考(即建立stub),或建立能在特定連接埠接收呼叫的遠端物件註冊服務程式。

伺服器端:向其他客戶機提供遠端物件服務

SomeService servcie=……;//远程对象服务

1、Registry registry=LocateRegisty.getRegistry();//Registry是個接口,他繼承了Remote,此方法傳回本地主機在預設註冊表連接埠1099 上對遠端物件Registry 的參考。

2、getRegistry(int port) 傳回本機在指定port 上對遠端物件Registry 的參考;

3、getRegistry(String host)  傳回指定host 在預設登錄機埠1099 上遠端物件Registry 的參考;

4、getRegistry(String host, int port) 傳回指定的host 和port 上對遠端物件Registry 的參考

#5、registry.bind(「I serve”,service);// bind(String name,Remote obj) 綁定對此註冊表中指定name 的遠端參考。 name : 與此遠端參考相關的名稱 obj : 移除遠端物件(通常是一個 stub)的參考

6、unbind(String name)移除註冊表中指定name的綁定。

7、rebind(String name,Remote obj)重新綁定,如果name已存在,但是Remote不一樣則替換,如果Remote一樣則丟棄現有的綁定

#8、 lookup(String name) 傳回註冊表中綁定到指定name 的遠端引用,傳回Remote

9、String[] list()   傳回在此登錄中所綁定的名稱的陣列。該陣列將包含一個此註冊表中呼叫此方法時綁定的名稱快照。

客戶機端:向伺服器提供對應的服務請求。

Registry registry=LocateRegisty.getRegistry();
SomeService servcie=(SomeService)registry.lookup(“I serve”);
Servcie.requestService();

Java RMI圖文詳解(附範例)

##(四) Naming類別和Registry類別類似。

客戶端:

Naming.lookup(String url)
url 格式如下"rmi://localhost/"+远程对象引用

伺服器端:

Registry registry=LocateRegistry.createRegistry(int port);
Naming.rebind(“service”,service);

(五) RMISecurityManager類別

在RMI引用程式中,如果沒有設定安全管理器,則只能從本機類別路徑載入stub和類,這可以確保應用程式不受遠端方法呼叫所下載的程式碼侵害

在從遠端主機下載程式碼之前必須執行下列程式碼來安裝RMISecurityManager:

System.setSecurityManager(new RMISecurityManager());

#第十、demo開發

###為了寫一個demo,我們分成兩個部分,一部分是server端的程式碼,一部分是client端的程式碼,client端的程式碼主要是為了使用server端的程式碼。當然這個程式碼是非常簡單的,只是為了說明問題,現實的使用會讓比較複雜的。 ######(一) 我們的目的######建立一個server端的java project,包含遠端的程式碼,定義接口,定義接口實現,然後在建立一個client端的java project,透過RMI使用遠端服務中的方法。 ######(二) 我們的程式碼結構###############(三) 遠端服務代碼######1. 遠端服務的介面定義### ###第一步就是建立和編譯服務介面的Java程式碼。這個介面定義了所有的提供遠端服務的功能,以下是原始程式:######UserManagerInterface.java###
package cn.com.tt.rmiserver.stub;

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

import cn.com.tt.rmiserver.bean.Account;

public interface UserManagerInterface extends Remote{
    public String getUserName() throws RemoteException;
    public Account getAdminAccount() throws RemoteException;
}
###介面必須繼承Remote類,每一個定義地方法都要拋出RemoteException異常對象。 ######2. 介面的具體實作######第二步就是對於上面的介面進行實作:######UserManagerImp.java###
package cn.com.tt.rmiserver;

import java.rmi.RemoteException;

import cn.com.tt.rmiserver.stub.UserManagerInterface;
import cn.com.tt.rmiserver.bean.Account;

public class UserManagerImp implements UserManagerInterface {
    public UserManagerImp() throws RemoteException {

    }
    private static final long serialVersionUID = -3111492742628447261L;

    public String getUserName() throws RemoteException{
        return "TT";
    }
    public Account getAdminAccount() throws RemoteException{
        Account account=new Account();
        account.setUsername("TT");
        account.setPassword("123456");
        return account;
    }
}
###3. 定義一個bean ,實作implements Serializable序列化介面。也就是可以在client和server端進行傳輸的可序列化物件。 ######Account.java###
package cn.com.tt.rmiserver.bean;

import java.io.Serializable;

public class Account implements Serializable,Cloneable{
    private static final long serialVersionUID = -1858518369668584532L;
    private String username;
    private String password;
    
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
}
###4. 定義server端的主程式入口。 ######Entry.java###
package cn.com.tt.rmiserver.entry;

import java.rmi.AlreadyBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import java.rmi.server.UnicastRemoteObject;

import cn.com.tt.rmiserver.UserManagerImp;
import cn.com.tt.rmiserver.stub.UserManagerInterface;

public class Entry {
    public static void main(String []args) throws AlreadyBoundException, RemoteException{
        UserManagerImp userManager=new UserManagerImp();
        UserManagerInterface userManagerI=(UserManagerInterface)UnicastRemoteObject.exportObject(userManager,0);
        // Bind the remote object's stub in the registry
        Registry registry = LocateRegistry.createRegistry(2002);
       
        registry.rebind("userManager", userManagerI);
        System.out.println("server is ready");
        }
}
###(四) client端程式碼###

1、把Server端的Account类和接口UserManagerInterface 导出Export成jar包,命名为:RmiServerInterface.jar。导入到client中。

2、项目——右键——Export——java——jar file——next——选择Account类和接口UserManagerInterface——命名为:RmiServerInterface.jar如下图:

Java RMI圖文詳解(附範例)

3. 新建一个java Project,导入jar包,编写客户端代码。

4. 代码

ClientEntry.java

package weiblog.rmi;

import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

import cn.com.tt.rmiserver.stub.UserManagerInterface;

public class ClientEntry {
    
    public static void main(String []args){
        
        try {
            Registry registry = LocateRegistry.getRegistry("localhost",2004);
            UserManagerInterface userManager = (UserManagerInterface)registry.lookup("userManager");
            System.out.println("用户名是"+userManager.getAdminAccount().getUsername()
                    +"密码"+userManager.getAdminAccount().getPassword());
        } catch (RemoteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NotBoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
    }

}

5. 先运行服务器端代码, 然后运行客户端代码,就会显示运行结果,客户端可以运行多次,每次都可以取得服务器端的对象。如果要再次运行客户端代码就需要更改端口号,如果不更改就会显示端口号被占用。

更多java知识请关注java基础教程栏目。

以上是Java RMI圖文詳解(附範例)的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文轉載於:博客园。如有侵權,請聯絡admin@php.cn刪除

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
1 個月前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
1 個月前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
1 個月前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它們
1 個月前By尊渡假赌尊渡假赌尊渡假赌

熱工具

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

ZendStudio 13.5.1 Mac

ZendStudio 13.5.1 Mac

強大的PHP整合開發環境

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具