欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解Java 中 RMI 的使用

 更新時(shí)間:2021年05月11日 09:44:49   作者:未讀代碼  
這篇文章主要介紹了Java 中 RMI 的使用,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

RMI 介紹

RMI (Remote Method Invocation) 模型是一種分布式對(duì)象應(yīng)用,使用 RMI 技術(shù)可以使一個(gè) JVM 中的對(duì)象,調(diào)用另一個(gè) JVM 中的對(duì)象方法并獲取調(diào)用結(jié)果。這里的另一個(gè) JVM 可以在同一臺(tái)計(jì)算機(jī)也可以是遠(yuǎn)程計(jì)算機(jī)。因此,RMI 意味著需要一個(gè) Server 端和一個(gè) Client 端。

Server 端通常會(huì)創(chuàng)建一個(gè)對(duì)象,并使之可以被遠(yuǎn)程訪問。

這個(gè)對(duì)象被稱為遠(yuǎn)程對(duì)象。Server 端需要注冊(cè)這個(gè)對(duì)象可以被 Client 遠(yuǎn)程訪問。

Client 端調(diào)用可以被遠(yuǎn)程訪問的對(duì)象上的方法,Client 端就可以和 Server 端進(jìn)行通信并相互傳遞信息。

說到這里,是不是發(fā)現(xiàn)使用 RMI 在構(gòu)建一個(gè)分布式應(yīng)用時(shí)十分方便,它和 RPC 一樣可以實(shí)現(xiàn)分布式應(yīng)用之間的互相通信,甚至和現(xiàn)在的微服務(wù)思想都十分類似。

RMI 工作原理

正所謂 “知其然知其所以然”,在開始編寫 RMI 代碼之前,有必要了解一下 RMI 的工作原理,RMI 中 Client 端是和 Server 端是如何通信的呢?

下圖的可以幫助我們理解RMI 的工作流程。

從圖中可以看到,Client 端有一個(gè)被稱 Stub 的東西,有時(shí)也會(huì)被成為存根,它是 RMI Client 的代理對(duì)象,Stub 的主要功能是請(qǐng)求遠(yuǎn)程方法時(shí)構(gòu)造一個(gè)信息塊,RMI 協(xié)議會(huì)把這個(gè)信息塊發(fā)送給 Server 端。

這個(gè)信息塊由幾個(gè)部分組成:

  • 遠(yuǎn)程對(duì)象標(biāo)識(shí)符。
  • 調(diào)用的方法描述。
  • 編組后的參數(shù)值(RMI協(xié)議中使用的是對(duì)象序列化)。

既然 Client 端有一個(gè) Stub 可以構(gòu)造信息塊發(fā)送給 Server 端,那么 Server 端必定會(huì)有一個(gè)接收這個(gè)信息快的對(duì)象,稱為 Skeleton 。

它主要的工作是:

  • 解析信息快中的調(diào)用對(duì)象標(biāo)識(shí)符和方法描述,在 Server 端調(diào)用具體的對(duì)象方法。
  • 取得調(diào)用的返回值或者異常值。
  • 把返回值進(jìn)行編組,返回給客戶端 Stub.

到這里,一次從 Client 端對(duì) Server 端的調(diào)用結(jié)果就可以獲取到了。

RMI 開發(fā)

通過上面的介紹,知道了 RMI 的概念以及 RMI 的工作原理,下面介紹 RMI 的開發(fā)流程。

這里會(huì)通過一個(gè)場(chǎng)景進(jìn)行演示,假設(shè) Client 端需要查詢用戶信息,而用戶信息存在于 Server 端,所以在 Server 端開放了 RMI 協(xié)議接口供客戶端調(diào)用查詢。

RMI Server

Server 端主要是構(gòu)建一個(gè)可以被傳輸?shù)念?User,一個(gè)可以被遠(yuǎn)程訪問的類 UserService,同時(shí)這個(gè)對(duì)象要注冊(cè)到 RMI 開放給客戶端使用。

1.定義服務(wù)器接口(需要繼承 Remote 類,方法需要拋出 RemoteException)。

package com.wdbyte.rmi.server;

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


/**
 * RMI Server
 *
 * @author www.wdbyte.com
 * @date 2021/05/08
 */
public interface UserService extends Remote {

    /**
     * 查找用戶
     * 
     * @param userId
     * @return
     * @throws RemoteException
     */
    User findUser(String userId) throws RemoteException;
}

User 對(duì)象在步驟 3 中定義。

2.實(shí)現(xiàn)服務(wù)器接口(需要繼承 UnicastRemoteObject 類,實(shí)現(xiàn)定義的接口)。

package com.wdbyte.rmi.server;

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

/**
 * @author www.wdbyte.com
 * @date 2021/05/08
 */
public class UserServiceImpl extends UnicastRemoteObject implements UserService {

    protected UserServiceImpl() throws RemoteException {
    }

    @Override
    public User findUser(String userId) throws RemoteException {
        // 加載在查詢
         if ("00001".equals(userId)) {
            User user = new User();
            user.setName("金庸");
            user.setAge(100);
            user.setSkill("寫作");
            return user;
        }
        throw new RemoteException("查無此人");
    }
}

3.定義傳輸?shù)膶?duì)象,傳輸?shù)膶?duì)象需要實(shí)現(xiàn)序列化(Serializable)接口。

需要傳輸?shù)念愐欢ㄒ獙?shí)現(xiàn)序列化接口,不然傳輸時(shí)會(huì)報(bào)錯(cuò)。IDEA 中如何生成 serialVersionUID,在文章末尾也附上了簡(jiǎn)單教程。

package com.wdbyte.rmi.server;

import java.io.Serializable;

/**
 *
 * @author www.wdbyte.com
 * @date 2021/05/08
 */
public class User implements Serializable {

    private static final long serialVersionUID = 6490921832856589236L;

    private String name;
    private Integer age;
    private String skill;

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getSkill() {
        return skill;
    }

    public void setSkill(String skill) {
        this.skill = skill;
    }
    
    @Override
    public String toString() {
        return "User{" +
            "name='" + name + '\'' +
            ", age=" + age +
            ", skill='" + skill + '\'' +
            '}';
    }
}

4.注冊(cè)( rmiregistry)遠(yuǎn)程對(duì)象,并啟動(dòng)服務(wù)端程序。

服務(wù)端綁定了 UserService 對(duì)象作為遠(yuǎn)程訪問的對(duì)象,啟動(dòng)時(shí)端口設(shè)置為 1900。

package com.wdbyte.rmi.server;

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

/**
 * RMI Server 端
 *
 * @author https://www.wdbyte.com
 * @date 2021/05/08
 */
public class RmiServer {

    public static void main(String[] args) {
        try {
            UserService userService = new UserServiceImpl();
            LocateRegistry.createRegistry(1900);
            Naming.rebind("rmi://localhost:1900/user", userService);
            System.out.println("start server,port is 1900");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

RMI Client

相比 Server 端,Client 端就簡(jiǎn)單的多。直接引入可遠(yuǎn)程訪問和需要傳輸?shù)念?,通過端口和 Server 端綁定的地址,就可以發(fā)起一次調(diào)用。

package com.wdbyte.rmi.client;

import java.rmi.Naming;

import com.wdbyte.rmi.server.User;
import com.wdbyte.rmi.server.UserService;

/**
 * @author https://www.wdbyte.com
 * @date 2021/05/08
 */
public class RmiClient {
    public static void main(String args[]) {
        User answer;
        String userId = "00001";
        try {
            // lookup method to find reference of remote object
            UserService access = (UserService)Naming.lookup("rmi://localhost:1900/user");
            answer = access.findUser(userId);
            System.out.println("query:" + userId);
            System.out.println("result:" + answer);
        } catch (Exception ae) {
            System.out.println(ae);
        }
    }
}

RMI 測(cè)試

啟動(dòng) Server 端。

start server,port is 1900

啟動(dòng) Client 端。

query:00001
result:User{name='金庸', age=100, skill='寫作'}

如果 Client 端傳入不存在的 userId。

java.rmi.ServerException: RemoteException occurred in server thread; nested exception is: 
	java.rmi.RemoteException: 查無此人

serialVersionUID 的生成

IDEA 中生成 serialVersionUID,打開設(shè)置,如下圖所示勾選。

選中要生成 serialVersionUID 的類,按智能提示快捷鍵。

參考

[1] https://docs.oracle.com/javase/tutorial/rmi/overview.html

到此這篇關(guān)于詳解Java 中 RMI 的使用的文章就介紹到這了,更多相關(guān)java RMI使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • visual studio 2019安裝配置可編寫c/c++語言的IDE環(huán)境

    visual studio 2019安裝配置可編寫c/c++語言的IDE環(huán)境

    這篇文章主要介紹了visual studio 2019安裝配置可編寫c/c++語言的IDE環(huán)境,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • webuploader 實(shí)現(xiàn)圖片批量上傳功能附實(shí)例代碼

    webuploader 實(shí)現(xiàn)圖片批量上傳功能附實(shí)例代碼

    這篇文章主要介紹了webuploader 實(shí)現(xiàn)圖片批量上傳功能,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2017-11-11
  • SpringBoot?SpringSecurity?JWT實(shí)現(xiàn)系統(tǒng)安全策略詳解

    SpringBoot?SpringSecurity?JWT實(shí)現(xiàn)系統(tǒng)安全策略詳解

    Spring?Security是Spring的一個(gè)核心項(xiàng)目,它是一個(gè)功能強(qiáng)大且高度可定制的認(rèn)證和訪問控制框架。它提供了認(rèn)證和授權(quán)功能以及抵御常見的攻擊,它已經(jīng)成為保護(hù)基于spring的應(yīng)用程序的事實(shí)標(biāo)準(zhǔn)
    2022-11-11
  • Maven配置倉庫的方法步驟

    Maven配置倉庫的方法步驟

    本文主要介紹了Maven配置倉庫的方法步驟,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • java二分查找插入法

    java二分查找插入法

    當(dāng)你需要構(gòu)建一個(gè)大的有序隊(duì)列,用插入發(fā)太慢了,可以先用二分查找法,找到在隊(duì)列要插入的位置,把數(shù)后移一下,然后放進(jìn)去。比較效率,下面是java使用示例,需要的朋友可以參考下
    2014-03-03
  • Deep Module深模塊之軟件設(shè)計(jì)

    Deep Module深模塊之軟件設(shè)計(jì)

    這篇文章主要介紹了軟件設(shè)計(jì)之Deep Module深模塊詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • 數(shù)組與List之間相互轉(zhuǎn)換的方法詳解

    數(shù)組與List之間相互轉(zhuǎn)換的方法詳解

    本文是對(duì)數(shù)組與List之間相互轉(zhuǎn)換的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友可以過來參考下。希望對(duì)大家有所幫助
    2013-10-10
  • SpringBoot整合MyBatis實(shí)現(xiàn)CRUD操作項(xiàng)目實(shí)踐

    SpringBoot整合MyBatis實(shí)現(xiàn)CRUD操作項(xiàng)目實(shí)踐

    本文主要介紹了SpringBoot整合MyBatis實(shí)現(xiàn)CRUD操作項(xiàng)目實(shí)踐,如何實(shí)現(xiàn)數(shù)據(jù)庫的CRUD創(chuàng)建、讀取、更新、刪除操作,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-02-02
  • JAVA程序員不得不留意的編碼規(guī)范

    JAVA程序員不得不留意的編碼規(guī)范

    這篇文章主要介紹了JAVA程序員不得不留意的編碼規(guī)范,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • SpringMVC中MultipartFile轉(zhuǎn)File的兩種方式

    SpringMVC中MultipartFile轉(zhuǎn)File的兩種方式

    在spring上傳文件中,一般都使用了MultipartFile來接收,但是有需要用到File的地方,本文主要介紹了SpringMVC中MultipartFile轉(zhuǎn)File的兩種方式,感興趣的可以了解一下
    2022-04-04

最新評(píng)論