SpringBoot裏使用RMI進行遠程方法調用 java序列化反序列化深刻探究

1、Java RMI定義

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

2、Java RMI工做原理

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

3、Java RMI的侷限

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

4、結構圖

5、代碼示例

1.代碼工程圖

 

 2.rmi-common

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

public interface IUserService {

    User getUserByName(String username);
    
}

3.rmi-server

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

@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

6、測試

@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")));
    }
}

 7、代碼地址

https://github.com/shaweiwei/sudu-rmi服務器

8、注意點

須要遠程傳輸的java bean必定要實現Serializable接口,具體爲啥看這篇 java序列化反序列化深刻探究網絡

相關文章
相關標籤/搜索