JDNI注入:RMI基本知識點介紹一
遠端方法呼叫,現在更多的使用RPC來處理,至於RMI好像沒有那麼多了,最近鬧的火熱的log4j2漏洞,又讓幾個關鍵詞jndi,rmi,ldap頻繁出現;對於我這種面向Spring程式設計的javer而言,這些是啥? 幹嘛用的?為啥漏洞這麼多?
接下來簡單學習下RMI的基本知識點
1. RMI科普
參考:http://www.jianshu.com/p/de85fad05dcb
Java RMI,即 遠端方法呼叫(Remote Method Invocation),一種用於實現遠端過程呼叫(RPC)(Remote procedure call)的Java API,能直接傳輸序列化後的Java物件和分散式垃圾收集。它的實現依賴於Java虛擬機器(JVM),因此它僅支援從一個JVM到另一個JVM的呼叫。
可以簡單的將RMI理解為jdk原生提供的rpc支援方式
2. 基礎體驗
基於上面的RMI架構圖,要體驗一下RMI的基本功能,非常簡單了
2.1 服務端
要提供一個rmi服務端就比較簡單了,不需要額外引入依賴,直接使用
類似於我們常見的rpc框架,先提供一個介面,終點注意它需要繼承 Remote
介面
import java.rmi.Remote;
public interface HelloService extends Remote {
// 方法丟擲異常,這個非常重要,不能少
String hello() throws RemoteException;
}
對應的實現類,重點注意繼承自 UnicastRemoteObject
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.time.LocalDateTime;
/**
* @author yihui
* @date 21/12/13
*/
public class HelloServiceImpl extends UnicastRemoteObject implements HelloService {
protected HelloServiceImpl() throws RemoteException {
}
@Override
public String hello() throws RemoteException {
return "hello: " + LocalDateTime.now();
}
}
最後就是啟動服務,提供一個上面的介面
public class RmiServer {
public static void main(String[] args) throws Exception {
Registry registry = LocateRegistry.createRegistry(8181);
// 建立一個遠端物件
HelloService hello = new HelloServiceImpl();
registry.bind("hello", hello);
System.out.println("服務已啟動");
Thread.currentThread().join();
}
}
2.2 客戶端
客戶端訪問rmi服務就很簡單了,兩行程式碼即可
public class RmiClient {
public static void main(String[] args) throws Exception{
Registry registry = LocateRegistry.getRegistry(8181);
HelloService hello = (HelloService) registry.lookup("hello");
String response = hello.hello();
System.out.println(response);
}
}
2.3 測試
先啟動服務端,再啟動客戶端,可以看到客戶端會拿到一個HelloService的例項,可以直接像呼叫本地方法一下訪問這個方法
注意上面這個case,客戶端拿到例項,訪問例項方法,這個邏輯是在哪裡執行的呢?(客戶端還是服務端?)
• 服務端執行(可以通過在實現類中新增一行日誌,看下這個日誌是在服務端輸出的還是客戶端輸出的)
3.naming方式
除了上面的這種方式之外,使用 Naming
方式的也非常普遍,如下
服務端,新的寫法如下
public static void main(String[] args) throws Exception {
Registry registry = LocateRegistry.createRegistry(8181);
Naming.bind("rmi://localhost:8181/hello", hello);
System.out.println("服務已啟動");
Thread.currentThread().join();
}
客戶端的寫法如下
public static void main(String[] args) throws Exception {
String remoteAddr="rmi://localhost:8181/hello";
HelloService hello = (HelloService) Naming.lookup(remoteAddr);
String response = hello.hello();
System.out.println(response);
}
這種方式與前面的效果相同,區別在於當有多個服務端時,使用naming的方式,可以指定ip + 埠號來獲取對應的服務提供者
一灰灰的聯絡方式
盡信書則不如無書,以上內容,純屬一家之言,因個人能力有限,難免有疏漏和錯誤之處,如發現bug或者有更好的建議,歡迎批評指正,不吝感激
• 個人站點:http://blog.hhui.top • 微博地址: 小灰灰Blog [1] • QQ:一灰灰/3302797840 • 微信公眾號: 一灰灰blog
References
[1]
小灰灰Blog: http://weibo.com/p/1005052169825577/home
- 基於MySql,Redis,Mq,ES的高可用方案解析
- 1w5字詳細介紹分散式系統的那些技術方案
- 程式設計師的浪漫:三十行程式碼實現用她的名字作幅畫
- 【WEB系列】內嵌Tomcat配置Accesslog日誌檔案生成位置原始碼探索
- 【搜尋系列】ES查詢常用例項演示
- 【搜尋系列】ES文件基本操作CURD例項演示
- 【搜尋系列】ES基本專案搭建
- Nosql儲存系統-叢集工作原理
- 例項演示,帶你瞭解終端神器ncat
- Redis:你真的會Redis麼,一文告訴你如何學習
- 常用設計模式彙總,告訴你如何學習設計模式
- 微服務閘道器:從對比到選型,由理論到實踐
- 【WEB系列】從0到1實現自定義web引數對映器
- SpringBoot系列Mybatis之批量插入的幾種姿勢
- SpringBoot系列Mybatis之ResultMap、ResultType返回結果使用姿勢
- 【DB系列】Mybatis之批量插入的幾種姿勢
- 【DB系列】Mybatis之ResultMap、ResultType返回結果使用姿勢
- 【中介軟體】Prometheus基於AOP實現埋點採集上報
- JDNI注入:RMI之繞過trustURLCodebase配置的注入例項演示三
- JDNI注入:RMI Reference引起的注入case二