RMI 远程调用实现
1、 java 中常见的 RPC 框架有:RMI, Hessian, gRPC, bRPC, dUBBO 等。 其实对于 RPC 框架而言,核心模块就是通讯和序列化。
2、 RMI :
1)RMI(remote method Invocation) 是 java 原生支持的远程调用。
RMI 采用 JRMP(Java RemoteMessageing Protocol)作为通信协议,
可以认为是纯 java 版本的分布式远程调用解决方案。
2)RMI 的核心概念:
Client --- 客户端从注册中心获取服务具体信息 ---> Registry 注册中心
Client --- 客户端调用服务端执行服务 ---> Server
Server --- 服务端在注册中心注册服务 ---> Registry 注册中心
3)RMI 步骤:
创建远程接口,并且继承 java.rmi.Remote 接口。
实现远程接口,并且继承 UnicastRemoteObject
创建服务程序,createRegistry() 方法注册远程对象。
创建客户端程序(获取注册信息,调用接口方法)。
3、 打开 idea 创建一个父 Maven 工程 rmi_demo 工程,和两个子模块(rmi_server, rmi_client)。
--> idea
--> File
--> New Project
--> Maven
--> Groupld : ( djh.it )
Artifactld : ( rmi_demo )
Version : 1.0-SNAPSHOT
--> Next
--> Project name: ( rmi_demo )
Project location: ( C:\java-test\idea2019\rmi_demo )
--> Finish
(父工程不编写代码,可以删除 src 目录)
创建两个子模块:
--> 右键 rmi_demo 父工程
--> Model
--> Maven
--> Groupld : ( djh.it )
Artifactld : ( rmi_server )
Version : 1.0-SNAPSHOT
--> Next
--> Module name: ( rmi_server )
Content root : ( C:\java-test\idea2019\rmi_demo\rmi_server )
Module file location: ( C:\java-test\idea2019\rmi_demo\rmi_server )
--> Finish
--> 右键 rmi_demo 父工程
--> Model
--> Maven
--> Groupld : ( djh.it )
Artifactld : ( rmi_client )
Version : 1.0-SNAPSHOT
--> Next
--> Module name: ( rmi_client )
Content root : ( C:\java-test\idea2019\rmi_demo\rmi_client )
Module file location: ( C:\java-test\idea2019\rmi_demo\rmi_client )
--> Finish
4 、在服务端子模块中( rmi_server 子工程中 ), 创建 远程接口 UserService.java 类,并且继承 java.rmi.Remote 接口
/**
* C:\java-test\idea2019\rmi_demo\rmi_server\src\main\java\djh\it\service\UserService.java
*
* 2024-3-10 RMI_RPC 远程调用实现:服务器端 server 接口 类
*
RMI 远程调用实现 步骤:
1)创建远程接口,并且继承 java.rmi.Remote 接口。
2)实现远程接口,并且继承 UnicastRemoteObject
3)创建服务程序,createRegistry() 方法注册远程对象。
4)创建客户端程序(获取注册信息,调用接口方法)。
*
*/
package djh.it.service;
import java.rmi.Remote;
import java.rmi.RemoteException;
// 1)创建远程接口,并且继承 java.rmi.Remote 接口。
public interface UserService extends Remote {
public String sayHello(String name) throws RemoteException;
}
5、 在服务端子模块中( rmi_server 子工程中 ), 创建 实现远程接口 UserServiceImpl.java 类,并且继承 UnicastRemoteObject
/**
* C:\java-test\idea2019\rmi_demo\rmi_server\src\main\java\djh\it\service\impl\UserServiceImpl.java
*
* 2024-3-10 RMI_RPC 远程调用实现:服务器端 server 实现 类
*
RMI 远程调用实现 步骤:
1)创建远程接口,并且继承 java.rmi.Remote 接口。
2)实现远程接口,并且继承 UnicastRemoteObject
3)创建服务程序,createRegistry() 方法注册远程对象。
4)创建客户端程序(获取注册信息,调用接口方法)。
*
*/
package djh.it.service.impl;
import djh.it.service.UserService;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
// 2)实现远程接口,并且继承 UnicastRemoteObject
public class UserServiceImpl extends UnicastRemoteObject implements UserService {
//构造方法
public UserServiceImpl() throws RemoteException {
}
//实现方法
public String sayHello (String name) throws RemoteException {
return name + "成功调用了服务端server";
}
}
6 、在服务端子模块中( rmi_server 子工程中 ), 创建服务程序 ServerMain.java , 以 createRegistry() 方法注册远程对象。
/**
* C:\java-test\idea2019\rmi_demo\rmi_server\src\main\java\djh\it\server\ServerMain.java
*
* 2024-3-10 RMI_RPC 远程调用实现:服务器端 服务程序 类
*
RMI 远程调用实现 步骤:
1)创建远程接口,并且继承 java.rmi.Remote 接口。
2)实现远程接口,并且继承 UnicastRemoteObject
3)创建服务程序,createRegistry() 方法注册远程对象。
4)创建客户端程序(获取注册信息,调用接口方法)。
*
*/
package djh.it.server;
import djh.it.service.UserService;
import djh.it.service.impl.UserServiceImpl;
import java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
// 3)创建服务程序,createRegistry() 方法注册远程对象。
public class ServerMain {
public static void main(String[] args) throws RemoteException, AlreadyBoundException, MalformedURLException {
//1.启动 RMI 注册服务,指定端口号
LocateRegistry.createRegistry(8888);
//2.创建要被访问的远程对象的实例
UserService userService = new UserServiceImpl();
//3.把远程对象实例注册到 RMI 注册服务器上
Naming.bind("rmi://localhost:8888/UserService", userService);
System.out.println("服务器启动中......");
}
}
7 、在客户端子模块中( rmi_client 子工程中 ), 创建客户端程序 ClientMain.java(获取注册信息,调用接口方法)。
/**
* C:\java-test\idea2019\rmi_demo\rmi_client\src\main\java\djh\it\client\ClientMain.java
*
* 2024-3-10 RMI_RPC 远程调用实现:客户端 client 程序 类
*
RMI 远程调用实现 步骤:
1)创建远程接口,并且继承 java.rmi.Remote 接口。
2)实现远程接口,并且继承 UnicastRemoteObject
3)创建服务程序,createRegistry() 方法注册远程对象。
4)创建客户端程序(获取注册信息,调用接口方法)。
*
*/
package djh.it.client;
import djh.it.service.UserService;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.Remote;
import java.rmi.RemoteException;
// 4)创建客户端程序(获取注册信息,调用接口方法)。
public class ClientMain {
public static void main(String[] args) throws RemoteException, NotBoundException, MalformedURLException {
//注意:客户端调用名称 要和 服务端一致(rmi://localhost:8888/UserService)
//客户端也要创建和服务端目录一致的 UserService.java 类
// 在客户端建立连接时,服务端程序必须先运行起来
UserService userService = (UserService) Naming.lookup("rmi://localhost:8888/UserService");
String 客户端 = userService.sayHello("客户端 -- ");
System.out.println(客户端);
}
}
8 、在客户端子模块中( rmi_client 子工程中 ),客户端 UserService 接口 类
/**
* C:\java-test\idea2019\rmi_demo\rmi_client\src\main\java\djh\it\service\UserService.java
*
* 2024-3-10 RMI_RPC 远程调用实现:客户端 UserService 接口 类
*
RMI 远程调用实现 步骤:
1)创建远程接口,并且继承 java.rmi.Remote 接口。
2)实现远程接口,并且继承 UnicastRemoteObject
3)创建服务程序,createRegistry() 方法注册远程对象。
4)创建客户端程序(获取注册信息,调用接口方法)。
*
*/
package djh.it.service;
import java.rmi.Remote;
import java.rmi.RemoteException;
// 1)创建远程接口,并且继承 java.rmi.Remote 接口。
public interface UserService extends Remote {
public String sayHello(String name) throws RemoteException;
}
9 、先启动 服务端 服务程序 类 ServerMain.java,
再启动 客户端 client 程序 类 ClientMain.java,
输出:客户端 -- 成功调用了服务端server