Java RMI

RMI概念

RMI系统提供跨JVM调用对象方法的机制。

RMI框架使用的接口、类与方法放在java.rmi包下。

RMI程序一般分为两部分,提供远程对象的Server与调用远程对象方法的Client,这种应用也被称为对象分布应用。

 

对象分布应用需要做以下工作:

定位远程对象、与远程对象沟通、加载对象的类定义

 

动态代码加载的优势

RMI可以跨JVM获取对象的类定义,这种机制扩展了程序的功能。

 

远程接口、对象、方法

远程对象:可以被跨JVM调用。

远程对象类:实现了远程接口的类。

远程接口:扩展了java.rmi.Remote接口,并且其中定义的每一个方法都会抛出一个java.rmi.RemoteException。

RMI的调用机制不是将远程对象跨JVM传输复制,而是获取一个远程对象的引用stub,这个引用相当于一个远程对象的代理。

Client通过调用传输到本地的stub调用方法,stub将远程方法的调用过程封装。

远程对象的方法中,只有定义在远程接口中的方法可以被调用。

 

编写rmi应用流程:

  • 设计远程接口,并且设计接口方法涉及的参数与返回值类型。
  • 设计远程对象。
  • 设计客户端,进行远程调用方法。

 

运行rmi应用程序流程:

  • server运行register
  • server运行编写的server端程序
  • client运行编写的client端程序

 

 

编写RMI Server

编写远程接口

public interface Compute extends Remote {	
	<T> T executeTask(Task<T> t) throws RemoteException;
}

ps:RMI远程调用方法时,传值使用的是序列化机制,如果方法参数是一个对象,此对象需要实现java.io.Serializiable接口。

ps:几乎一切类型的数据都可以作为远程接口返回值或参数。即,基础类型、远程对象、本地对象。远程接口中参数、返回值涉及到的对象,都是值传递,即在receiver中生成一个副本,sender中的对象的状态变化与receiver中副本对象状态的变化无关。

 

RMI Server主程序流程

  • 创建install SecurityManager对象,用于对系统资源访问进行控制。
  • 创建远程对象,获取远程对象引用stub
  • 获取本地register的远程对象引用
  • 设置远程对象引用的name,然后将其与远程对象引用一起bind进register

 

创建install ScurityMnager对象

if(System.getSecurityManager() == null) {
    System.setSecurityManager(new SecurityManager());
}

 

创建一个远程对象,并且获取其远程对象引用stub

Compute engine = new ComputeEngine();
Compute stub = (Compute)UnicastRemoteObject.exportObject(engine, 0);

ps:stub是一个远程接口类型的代理对象。静态方法的第二个参数用于设置接收方法调用请求的TCP端口,将其设置为0时,表示使用匿名端口,即端口在运行时由RMI与操作系统共同决定。

ps:exportObject方法声明会抛出一个RemoteException,此异常为checked异常,所以需要处理。

 

获取本地主机的register远程对象

Registry registry = LocateRegistry.getRegistry();

note:获取本地主机的register的远程对象。

ps:registry远程对象用于设置其他的远程对象,此远程对象在使用getRegistry()方法不传参获得时,默认使用1099作为端口。

ps:registry远程对象用于使用name字符串查找其他远程对象。

 

将远程对象设置进registry

registry.rebind(name, stub);

note:将远程对象stub与字符串name绑定。

ps:绑定进register中的引用,可以通过name直接获取。
ps:设置后之后,不需要再设置一个线程用于等待请求,可以直接结束代码,此时远程对象不会被GC处理掉,而是会等待远程Client调用。

 

 

编写RMI Client

RMI Client主程序流程

  • 创建install SecurityManager对象
  • 获取远程主机的register的远程对象引用
  • 利用register获取远程对象引用stub
  • 通过stub操作远程对象

 

获取指定主机的register远程对象

Registry registry = LocateRegistry.getRegistry(host);

note:通过host与默认端口1099获取指定register远程对象。

 

通过register获取远程对象

Compute compute = (Compute) registry.lookup(name);

 

 

运行RMI分布式应用

运行register

start rmiregistry

ps:运行在server端

 

运行server端

java -cp D:\DevelopmentSpace\compute.jar -Djava.rmi.server.codebase=file:/D:/DevelopmentSpace/compute.jar -Djava.rmi.server.hostname=mycomputer.example.com -Djava.security.policy=server.policy engine.ComputeEngine

note:运行engine.ComputeEngine

ps:codebase设置client端获取服务器class文件的url路劲,policy设置安全策略文件

 

运行客户端

java -cp D:\DevelopmentSpace\compute.jar -Djava.rmi.server.codebase=file:/D:/DevelopmentSpace/compute.jar  -Djava.security.policy=server.policy client.ComputePi

note:运行client.ComputePi

 

 

详细教程:https://docs.oracle.com/javase/tutorial/rmi/overview.html

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值