RMI 远程方法调用
在分布式系统中系统之间需要有一种网络通讯的方式,RMI(Remote Method Invocation)是Java内置的远程方法调用模块,RMI基于JDK的序列化机制和TCP网络协议实现,它也是EJB的基础。
RMI的同类技术
实际上,远程调用的方法还有很多种,比如各种基于TCP的远过程调用实现,甚至基于HTTP的SOAP、REST等方式。在所有这些常用的方式中,RMI是最稳定高效的,但缺点是只能Java程序之间使用。
RMI示例
我们这里直接编写一个例子来学习如何使用RMI,工程目录结构如下。
demo
|_ src/main/java
|_ com.gacfox.demo
|_ beans
|_ User.java
|_ service
|_ UserService.java
|_ UserServiceImpl.java
|_ Client.java
|_ LaunchService.java
实现RMI服务端
我们这里创建一个实体类User
作为RMI传递的对象。
@Data
@Builder
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private String username;
private String password;
}
下面代码编写了一个RMI的Service接口。
public interface UserService extends Remote {
User getUser() throws RemoteException;
}
RMI接口需要继承Remote
接口,其中方法需要抛出RemoteException
,接口实现类如下。
public class UserServiceImpl extends UnicastRemoteObject implements UserService {
private static final long serialVersionUID = 1L;
public UserServiceImpl() throws RemoteException {
super();
}
@Override
public User getUser() throws RemoteException {
User user = User.builder().username("tom").password("123456").build();
return user;
}
}
实现类必须继承UnicastRemoteObject
,并带有一个默认构造函数。其中getUser()
是我们定义的远程调用的方法,最后我们需要注册RMI服务。
public class LaunchService {
public static void main(String[] args) throws Exception {
UserService userService = new UserServiceImpl();
LocateRegistry.createRegistry(8080);
Naming.rebind("rmi://127.0.0.1:8080/UserService", userService);
System.out.println("服务已启动");
}
}
这里我们将UserService
注册到rmi://127.0.0.1:8080/UserService
。如果要注册多个服务,使用Naming.rebind()
多添加几个路径就行了。
绑定路径时,RMI提供了bind()
和rebind()
两个方法,区别就是bind()
会在地址冲突时报错,rebind()
则不会报错,而是丢弃原来的绑定,使用新的。在实际使用中,正确的代码逻辑一般不会重复绑定一个地址的,所以用哪个都行。
实现RMI客户端
RMI客户端直接对服务端注册的RMI地址进行调用即可。
public class Client {
public static void main(String[] args) throws Exception {
UserService userService = (UserService) Naming.lookup("rmi://127.0.0.1:8080/UserService");
User user = userService.getUser();
System.out.println(user);
}
}
作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。