知識庫 / Spring RSS 訂閱

Spring Remoting 與 RMI

Spring
HongKong
3
02:26 PM · Dec 06 ,2025

1. 概述

Java 的 遠程方法調用 (Remote Method Invocation, RMI) 允許在不同的 Java 虛擬機 中調用對象。 儘管這是一種成熟的技術,但由於其使用起來有些繁瑣,正如 Oracle 官方的關於該主題的教程 http://docs.oracle.com/javase/tutorial/rmi/index.html 所展示的,但其使用起來有些繁瑣。

在本文中,我們將探討如何通過 Spring Remoting 更輕鬆、更簡潔地利用 RMI。

本文還完成了對 Spring Remoting 的概述。 您可以在之前的章節中找到有關其他支持的技術的詳細信息: HTTP 調用者、JMS、AMQP、Hessian 和 Burlap。

2. Maven 依賴項

正如我們在之前的文章中所做的那樣,我們將設置兩個 Spring Boot 應用程序:一個暴露遠程可調用對象的服務器和一個調用該服務的客户端。

我們需要的一切都包含在 spring-context 庫中——因此我們可以使用我們喜歡的任何 Spring Boot 輔助工具將其引入——因為我們的主要目標只是提供主要庫。

現在,讓我們繼續使用標準的 spring-boot-starter-web,同時記住要刪除 Tomcat 依賴項以排除嵌入式 Web 服務:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
        </exclusion>
    </exclusions>
</dependency>

3. 服務器應用程序

我們將聲明一個接口,該接口定義了一個用於預訂出租車行程的服務,該服務最終將暴露給客户端。

public interface CabBookingService {
    Booking bookRide(String pickUpLocation) throws BookingException;
}

然後,我們將定義一個實現該接口的 Bean。這個 Bean 將實際在服務器端執行業務邏輯:

@Bean 
CabBookingService bookingService() {
    return new CabBookingServiceImpl();
}

讓我們繼續聲明用於向客户端提供服務的 Exporter。在這種情況下,我們將使用 RmiServiceExporter

@Bean 
RmiServiceExporter exporter(CabBookingService implementation) {
    Class<CabBookingService> serviceInterface = CabBookingService.class;
    RmiServiceExporter exporter = new RmiServiceExporter();
    exporter.setServiceInterface(serviceInterface);
    exporter.setService(implementation);
    exporter.setServiceName(serviceInterface.getSimpleName());
    exporter.setRegistryPort(1099); 
    return exporter;
}

通過 setServiceInterface(),我們提供了一個可以遠程調用的接口引用。

我們還應該提供一個引用實際執行方法的對象的引用,通過 setService()。 這樣,如果不想使用默認端口 1099,我們還可以提供服務器運行機器上 RMI 註冊表 的端口。

我們還應該設置一個服務名稱,以便在 RMI 註冊表中識別暴露的服務。

在給定的配置下,客户端將能夠通過以下 URL 聯繫 CabBookingServicermi://HOST:1199/CabBookingService

最後,讓我們啓動服務器。 由於 Spring 會自動為我們啓動 RMI 註冊表(如果未找到),因此我們不需要手動啓動它。

4. 客户端應用程序

現在我們來編寫客户端應用程序。

我們首先聲明 RmiProxyFactoryBean,它將創建一個 bean,該 bean 與服務器端運行的服務公開的接口相同,並且它將接收到的所有調用透明地路由到服務器。

@Bean 
RmiProxyFactoryBean service() {
    RmiProxyFactoryBean rmiProxyFactory = new RmiProxyFactoryBean();
    rmiProxyFactory.setServiceUrl("rmi://localhost:1099/CabBookingService");
    rmiProxyFactory.setServiceInterface(CabBookingService.class);
    return rmiProxyFactory;
}

讓我們編寫一段簡單的代碼,啓動客户端應用程序並使用之前步驟中定義的代理:

public static void main(String[] args) throws BookingException {
    CabBookingService service = SpringApplication
      .run(RmiClient.class, args).getBean(CabBookingService.class);
    Booking bookingOutcome = service
      .bookRide("13 Seagate Blvd, Key Largo, FL 33037");
    System.out.println(bookingOutcome);
}

現在只需啓動客户端以驗證它是否調用了服務器端提供的服務。

5. 結論

在本教程中,我們看到了如何使用 Spring Remoting 來簡化 RMI 的使用,否則 RMI 需要執行一系列繁瑣的任務,例如啓動註冊表並使用接口定義服務,這些接口大量使用 checked 異常。

user avatar
0 位用戶收藏了這個故事!
收藏

發佈 評論

Some HTML is okay.