SpringBoot里使用RMI進行遠程方法調用


一、Java RMI定義

Java RMI:Java遠程方法調用,即Java RMI(Java Remote Method Invocation)是Java編程語言里,一種用於實現遠程過程調用的應用程序編程接口。它使客戶機上運行的程序可以調用遠程服務器上的對象。遠程方法調用特性使Java編程人員能夠在網絡環境中分布操作。RMI全部的宗旨就是盡可能簡化遠程接口對象的使用。

二、Java RMI工作原理

RMI能讓一個Java程序去調用網絡中另一台計算機的Java對象的方法,那么調用的效果就像是在本機上調用一樣。通俗的講:A機器上面有一個class,通過遠程調用,B機器調用這個class 中的方法。
RMI,遠程方法調用(Remote Method Invocation)是Enterprise JavaBeans的支柱,是建立分布式Java應用程序的方便途徑。RMI是非常容易使用的,但是它非常的強大。
RMI的基礎是接口,RMI構架基於一個重要的原理:定義接口和定義接口的具體實現是分開的。

三、Java RMI的局限

RMI目前使用Java遠程消息交換協議JRMP(Java Remote Messaging Protocol)進行通信。JRMP是專為Java的遠程對象制定的協議,由於JRMP是專為Java對象制定的,因此,RMI對於用非Java語言開發的應用系統的支持不足。不能與用非Java語言書寫的對象進行通信(意思是只支持客戶端和服務器端都是Java程序的代碼的遠程調用)。

四、結構圖

五、代碼示例

1.代碼工程圖

 

 2.rmi-common

這個工程主要是存放client和server都會用到的公共接口。

public interface IUserService {

    User getUserByName(String username);
    
}

3.rmi-server

主要提供接口的實現以及rmi的服務配置。

@SpringBootApplication
public class RmiBootServer {

    @Autowired
    private IUserService userService;
    
    @Autowired
    private IPermissionService permissionService;
    
    @Bean
    public RmiServiceExporter rmiServiceExporter(){
        RmiServiceExporter rmiServiceExporter = new RmiServiceExporter();
        rmiServiceExporter.setServiceName("userService");
        rmiServiceExporter.setService(userService);
        rmiServiceExporter.setServiceInterface(IUserService.class);
        rmiServiceExporter.setRegistryPort(2002);// 默認為1099,注意占用問題
        try {
            rmiServiceExporter.afterPropertiesSet();
        } catch (RemoteException e) {
            e.printStackTrace();
        }
        return rmiServiceExporter;
    }
    
    public static void main(String[] args) {
        SpringApplication.run(RmiBootServer.class, args);
    }
}
@Service
public class UserServiceImpl implements IUserService {

    @Override
    public User getUserByName(String username) {
        User user = null;
        if (username != null && !username.equals("")) {
            user = new User();
            if (username.equals("admin")) {
                user.setUsername("admin");
                user.setPassword("123456");
            }else{
                user.setUsername("xxxx");
                user.setPassword("111111");
            }
            
        }
        return user;
    }

}
server:
  port: 8002

4.rmi-client

本地client如何實現調用遠程的接口實現。

@SpringBootApplication
public class RmiBootClient {
    
    @Bean
    public RmiProxyFactoryBean rmiProxyFactoryBean(){
        RmiProxyFactoryBean rmiProxyFactoryBean = new RmiProxyFactoryBean();
        rmiProxyFactoryBean.setServiceUrl("rmi://127.0.0.1:2002/userService");
        rmiProxyFactoryBean.setServiceInterface(IUserService.class);
        return rmiProxyFactoryBean;
        
    }
    
    public static void main(String[] args) {
        SpringApplication.run(RmiBootClient.class, args);
    }
}
server:
  port: 8001
  
logging:
  level:
    root: info

六、測試

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes=RmiBootClient.class,
        webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@Slf4j
public class RmiTest {
    
    Gson gson = new Gson();

    @Autowired
    private IUserService userService;
    
    @Test
    public void getUser(){
        log.info("get user{}",gson.toJson(userService.getUserByName("admin")));
    }
}

 七、代碼地址

https://github.com/shaweiwei/sudu-rmi

八、注意點

需要遠程傳輸的java bean一定要實現Serializable接口,具體為啥看這篇 java序列化反序列化深入探究


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM