成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Java 中 RMI 的使用

開發 后端
RMI (Remote Method Invocation) 模型是一種分布式對象應用,使用 RMI 技術可以使一個 JVM 中的對象,調用另一個 JVM 中的對象方法并獲取調用結果。這里的另一個 JVM 可以在同一臺計算機也可以是遠程計算機。

[[398352]]

本文轉載自微信公眾號「未讀代碼」,作者未讀君 。轉載本文請聯系未讀代碼公眾號。

RMI 介紹

RMI (Remote Method Invocation) 模型是一種分布式對象應用,使用 RMI 技術可以使一個 JVM 中的對象,調用另一個 JVM 中的對象方法并獲取調用結果。這里的另一個 JVM 可以在同一臺計算機也可以是遠程計算機。因此,RMI 意味著需要一個 Server 端和一個 Client 端。

Server 端通常會創建一個對象,并使之可以被遠程訪問。

  • 這個對象被稱為遠程對象。
  • Server 端需要注冊這個對象可以被 Client 遠程訪問。

Client 端調用可以被遠程訪問的對象上的方法,Client 端就可以和 Server 端進行通信并相互傳遞信息。

說到這里,是不是發現使用 RMI 在構建一個分布式應用時十分方便,它和 RPC 一樣可以實現分布式應用之間的互相通信,甚至和現在的微服務思想都十分類似。

RMI 工作原理

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

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

RMI Connection

從圖中可以看到,Client 端有一個被稱 Stub 的東西,有時也會被成為存根,它是 RMI Client  的代理對象,Stub 的主要功能是請求遠程方法時構造一個信息塊,RMI 協議會把這個信息塊發送給 Server 端。

這個信息塊由幾個部分組成:

  • 遠程對象標識符。
  • 調用的方法描述。
  • 編組后的參數值(RMI協議中使用的是對象序列化)。

既然 Client 端有一個 Stub 可以構造信息快發送給 Server 端,那么 Server 端必定會有一個接收這個信息快的對象,稱為 Skeleton 。

它主要的工作是:

解析信息塊中的調用對象標識符和方法描述,在 Server 端調用具體的對象方法。

取得調用的返回值或者異常值。

把返回值進行編組,返回給客戶端 Stub.

到這里,一次從  Client 端對 Server 端的調用結果就可以獲取到了。

RMI 開發

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

這里會通過一個場景進行演示,假設 Client 端需要查詢用戶信息,而用戶信息存在于 Server 端,所以在 Server 端開放了 RMI 協議接口供客戶端調用查詢。

RMI Server

Server 端主要是構建一個可以被傳輸的類 User,一個可以被遠程訪問的類 UserService,同時這個對象要注冊到 RMI 開放給客戶端使用。

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

  1. package com.wdbyte.rmi.server; 
  2.  
  3. import java.rmi.Remote; 
  4. import java.rmi.RemoteException; 
  5.  
  6.  
  7. /** 
  8.  * RMI Server 
  9.  * 
  10.  * @author www.wdbyte.com 
  11.  * @date 2021/05/08 
  12.  */ 
  13. public interface UserService extends Remote { 
  14.  
  15.     /** 
  16.      * 查找用戶 
  17.      *  
  18.      * @param userId 
  19.      * @return 
  20.      * @throws RemoteException 
  21.      */ 
  22.     User findUser(String userId) throws RemoteException; 

User 對象在步驟 3 中定義。

實現服務器接口(需要繼承 UnicastRemoteObject 類,實現定義的接口)。

  1. package com.wdbyte.rmi.server; 
  2.  
  3. import java.rmi.RemoteException; 
  4. import java.rmi.server.UnicastRemoteObject; 
  5.  
  6. /** 
  7.  * @author www.wdbyte.com 
  8.  * @date 2021/05/08 
  9.  */ 
  10. public class UserServiceImpl extends UnicastRemoteObject implements UserService { 
  11.  
  12.     protected UserServiceImpl() throws RemoteException { 
  13.     } 
  14.  
  15.     @Override 
  16.     public User findUser(String userId) throws RemoteException { 
  17.         // 加載在查詢 
  18.          if ("00001".equals(userId)) { 
  19.             User user = new User(); 
  20.             user.setName("金庸"); 
  21.             user.setAge(100); 
  22.             user.setSkill("寫作"); 
  23.             return user
  24.         } 
  25.         throw new RemoteException("查無此人"); 
  26.     } 

定義傳輸的對象,傳輸的對象需要實現序列化(Serializable)接口。

需要傳輸的類一定要實現序列化接口,不然傳輸時會報錯。IDEA 中如何生成 serialVersionUID,在文章末尾也附上了簡單教程。

  1. package com.wdbyte.rmi.server; 
  2.  
  3. import java.io.Serializable
  4.  
  5. /** 
  6.  * 
  7.  * @author www.wdbyte.com 
  8.  * @date 2021/05/08 
  9.  */ 
  10. public class User implements Serializable { 
  11.  
  12.     private static final long serialVersionUID = 6490921832856589236L; 
  13.  
  14.     private String name
  15.     private Integer age; 
  16.     private String skill; 
  17.  
  18.     public String getName() { 
  19.         return name
  20.     } 
  21.  
  22.     public void setName(String name) { 
  23.         this.name = name
  24.     } 
  25.  
  26.     public Integer getAge() { 
  27.         return age; 
  28.     } 
  29.  
  30.     public void setAge(Integer age) { 
  31.         this.age = age; 
  32.     } 
  33.  
  34.     public String getSkill() { 
  35.         return skill; 
  36.     } 
  37.  
  38.     public void setSkill(String skill) { 
  39.         this.skill = skill; 
  40.     } 
  41.      
  42.     @Override 
  43.     public String toString() { 
  44.         return "User{" + 
  45.             "name='" + name + '\'' + 
  46.             ", age=" + age + 
  47.             ", skill='" + skill + '\'' + 
  48.             '}'
  49.     } 

注冊( rmiregistry)遠程對象,并啟動服務端程序。

服務端綁定了 UserService 對象作為遠程訪問的對象,啟動時端口設置為 1900。

  1. package com.wdbyte.rmi.server; 
  2.  
  3. import java.rmi.Naming; 
  4. import java.rmi.registry.LocateRegistry; 
  5.  
  6. /** 
  7.  * RMI Server 端 
  8.  * 
  9.  * @author https://www.wdbyte.com 
  10.  * @date 2021/05/08 
  11.  */ 
  12. public class RmiServer { 
  13.  
  14.     public static void main(String[] args) { 
  15.         try { 
  16.             UserService userService = new UserServiceImpl(); 
  17.             LocateRegistry.createRegistry(1900); 
  18.             Naming.rebind("rmi://localhost:1900/user", userService); 
  19.             System.out.println("start server,port is 1900"); 
  20.         } catch (Exception e) { 
  21.             e.printStackTrace(); 
  22.         } 
  23.     } 

RMI Client

相比 Server 端,Client 端就簡單的多。直接引入可遠程訪問和需要傳輸的類,通過端口和 Server 端綁定的地址,就可以發起一次調用。

  1. package com.wdbyte.rmi.client; 
  2.  
  3. import java.rmi.Naming; 
  4.  
  5. import com.wdbyte.rmi.server.User
  6. import com.wdbyte.rmi.server.UserService; 
  7.  
  8. /** 
  9.  * @author https://www.wdbyte.com 
  10.  * @date 2021/05/08 
  11.  */ 
  12. public class RmiClient { 
  13.     public static void main(String args[]) { 
  14.         User answer; 
  15.         String userId = "00001"
  16.         try { 
  17.             // lookup method to find reference of remote object 
  18.             UserService access = (UserService)Naming.lookup("rmi://localhost:1900/user"); 
  19.             answer = access.findUser(userId); 
  20.             System.out.println("query:" + userId); 
  21.             System.out.println("result:" + answer); 
  22.         } catch (Exception ae) { 
  23.             System.out.println(ae); 
  24.         } 
  25.     } 

RMI  測試

啟動 Server 端。

  1. start server,port is 1900 

啟動 Client 端。

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

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

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

serialVersionUID 的生成

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

IDEA 設置

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

IDEA serialVersionUID

參考

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

 

責任編輯:武曉燕 來源: 未讀代碼
相關推薦

2012-04-11 11:10:25

JavaRMI

2011-03-28 10:42:00

Spring

2012-02-07 13:21:37

Java

2018-02-28 14:04:08

RMIJDBC存儲

2009-06-19 14:23:41

RMIJava分布式計算

2010-08-25 17:08:18

實例教程

2013-05-29 09:59:20

Java-RMI遠程調用

2016-09-18 16:58:09

JavaProperties

2009-06-08 21:49:25

RowSetJava

2012-03-27 14:04:54

JavaEnum

2019-06-21 14:48:25

RMI遠程RPC

2017-09-23 15:28:32

JavaOptional方法

2012-06-02 00:53:39

Javafinally

2018-06-12 15:10:49

RPCRM企業

2021-04-13 09:20:21

JavaUnsafejava8

2024-01-31 08:53:01

Java數組代碼

2010-03-11 15:39:01

Python編程語言

2024-01-30 09:43:43

Java緩存技術

2016-11-03 18:39:39

JavaMySQL

2024-01-11 13:21:53

開發代碼
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩视频精品 | 国产精品中文字幕在线 | 国产精品性做久久久久久 | 国产成人99久久亚洲综合精品 | 精品伦精品一区二区三区视频 | 99亚洲精品 | www.youjizz.com日韩| 久久国产精品免费一区二区三区 | 久久精品免费一区二区三 | 国产高清一区二区三区 | 国产欧美在线一区 | 久久综合久 | 亚洲综合区 | 亚洲成人免费视频在线 | 国产黄色av网站 | 中文字幕亚洲区 | 日韩在线一区二区 | 中文字幕一区二区三区在线观看 | 亚洲成人精品一区 | 久久久久久成人 | 国家一级黄色片 | 欧美精品久久久久 | 黄色网址大全在线观看 | 最新国产精品视频 | 国产成人精品久久二区二区91 | 欧美区在线观看 | 久久免费高清视频 | 日韩av免费在线电影 | 免费人成在线观看网站 | 久久精品国产一区二区三区 | 99视频免费在线 | 毛片视频免费 | 久久精品亚洲一区二区三区浴池 | 久久久高清 | 国产精品日韩一区 | 亚洲精品一区中文字幕乱码 | 久久av一区二区三区 | 精品一区二区三区日本 | 中文字幕一区二区三区精彩视频 | 亚洲图片一区二区三区 | 黄色一级大片在线观看 |