玩玩RMI
今天在看代理设计模式,java中远程代理的实现一定会用到RMI的,很久没有温习过RMI的知识了,今天就重新过一遍这个知识点来让自己加深印象,构建一个简单的RMI小程序需要用到一下几个类:
- java.rmi.Remote
- java.rmi.RemoteException
- java.rmi.Naming
UML类图:

类图很简单,但是有几点需要注意:
- 服务器端的接口应该继承自java.rmi.server.UnicastRemoteObject类并实现java.rmi.Remote接口
- 由于是远程方法调用,有可能由于网络原因而出现异常,服务器端接口的方法应该抛出java.rmi.RemoteException
- 服务器端接口的具体实现类必须显示地声明一个无参构造方法并抛出RemoteException, 这是因为UnicastRemoteObject类的无参构造方法就抛出了RemoteException,这样在实例化MyRemoteImpl之前会先实例化UnicastRemoteObject
- 由于参数和返回值需要在网络中传播,如果你的参数和返回值不是java原始数据类型(例如自定义的对象),那么该对象需要实现java.io.Serializable, 这样JVM才能对该对象进行序列及反序列化
我们再来看看具体的实现:
MyRemote接口
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface MyRemote extends Remote {
public String getServerTime(String employee) throws RemoteException;
}
MyRemoteImpl实现类
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.Date;
public class MyRemoteImpl extends UnicastRemoteObject implements MyRemote {
private static final long serialVersionUID = 6812592847867041499L;
public MyRemoteImpl() throws RemoteException {
super();
}
public static void main(String[] args) throws MalformedURLException, RemoteException, AlreadyBoundException {
MyRemote myRemote = new MyRemoteImpl();
Naming.bind("rmi://192.168.3.4:1099/myRemote", myRemote);
System.out.println("Ready...");
}
@Override
public String getServerTime(String employee) throws RemoteException {
return String.format("Hello %s, Italy time is: %s", employee, new Date());
}
}
客户端测试类:
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
public class RmiClient {
public static void main(String[] args) throws MalformedURLException, RemoteException, NotBoundException {
MyRemote myRemote = (MyRemote) Naming.lookup("rmi://192.168.3.4:1099/myRemote");
System.out.println(myRemote.getServerTime("Linda"));
}
}
现在运行测试还为时尚早,为了实现跨JVM的远程方法调用我们还需要做一些必须的事情:
- 使用rmic工具生成Stub桩供远程调用(Java 1.5之后可以不用生成这个文件?还在研究)
- rmiregistry开放RMI注册
- 使用java.rmi.Naming的bind方法来绑定服务
我们一步一步来:
首先生成stub文件,客户端需要这个文件来调用远程对象,这个文件其实就是远程对象在本地的一个代理,客户端以为是跟远程对象直接打交道,其实客户端调用的是该客户服务对象,该桩又调用远程对象。

生成的桩文件:

运行rmiregistry命令:

运行MyRemoteImpl的main方法来将服务绑定到远程计算机的1099端口

我们写的是一个RMI程序,为了测试跨内存空间(跨JVM)的远程方法调用,我把服务器端的以下class文件放到了国外服务器上面:
- MyRemote.class
- MyRemoteImpl.class
- MyRemoteImpl_Stub.class
把以下客户端的class放到本地:
- MyRemote.class
- MyRemoteImpl_Stub.class
- RmiClient.class
现在让我来测试一下,运行命令:
java RmiClient

从运行结果可以看出来,本地客户端成功调用到了远在欧洲的对象并把String值返回到了本地通过控制台打印出来。下一个待解决的问题是如何可以不需要stub文件来进行远程方法调用,正在学习中。
玩玩RMI的更多相关文章
- tomcat RMI 停不掉
项目采用jfinal框架,做了一个RMI的服务,对其它程序提供服务.实现上,写了一个RmiPlugin package com.wisdombud.cloudtalk.plugin; import j ...
- Exception thrown by the agent : java.rmi.server.ExportException: Port already in use
今天有个应用一直起不来,感觉配置都对啊,奇了怪了.看日志发现如下: STATUS | wrapper | 2017/01/04 08:09:31 | Launching a JVM...INFO | ...
- RMI(远程接口调用)
1. RMI的原理: RMI系统结构,在客户端和服务器端都有几层结构. 方法调用从客户对象经占位程序(Stub).远程引用层(Remote Reference Layer)和传输层(Transport ...
- Java RMI之HelloWorld篇
Java RMI 指的是远程方法调用 (Remote Method Invocation).它是一种机制,能够让在某个 Java 虚拟机上的对象调用另一个 Java 虚拟机中的对象上的方法.可以用此方 ...
- Spring远程调用技术<1>-RMI
在java中,我们有多种可以使用的远程调用技术 1.远程方法调用(remote method invocation, RMI) 适用场景:不考虑网络限制时(例如防火墙),访问/发布基于java的服务 ...
- Java的RMI远程方法调用实现和应用
最近在学习Dubbo,RMI是很重要的底层机制,RMI(Remote Method Invocation)远程方法调用是一种计算机之间利用远程对象互相调用实现双方通讯的一种通讯机制.使用这种机制,某一 ...
- Java远程方法调用(Remote Method Invocation,RMI)
Java RMI简介: 它是Java的一个核心API和类库,允许一个Java虚拟机上运行的Java程序调用不同虚拟机上运行的对象中的方法,即使这两个虚拟机运行于物理隔离的不同主机上. Java RMI ...
- 启动tomcat时 错误: 代理抛出异常 : java.rmi.server.ExportException: Port already in use: 1099;
错误: 代理抛出异常 : java.rmi.server.ExportException: Port already in use: 1099; nested exception is: java ...
- JAVA RMI 实例
下面我将介绍一个完整的实例,让初学者能快速体验RMI的功用. 分为以下四个步骤 1. 创建远程接口及声明远程方法(HelloInterface.java)2. 实现远程接口及远程方法(继承Unicas ...
随机推荐
- 面试题-JDBC
1.什么是JDBC? JDBC是允许用户在不同数据库之间做选择的一个抽象层.JDBC允许开发者用JAVA写数据库应用程序,而不需要关心底层特定数据库的细节. 2.解释下驱动(Driver)在JDBC中 ...
- 导入excel成一个list集合不支持大文件倒入(优化点在于分批分线程导入)
package com.bj58.saletb.news.utils; import org.apache.log4j.Logger; import org.apache.poi.ss.usermod ...
- 关于高性能javascript 笔记
最近买了本新书,准备自己吃 狗粮的同时也吃点精神食粮.笔记总结,从现在开始,看我啥时候能看完这本酥,就酱紫, begin:
- AppCan 双击返回按钮退出应用
使用AppCan开发手机应用,拦截返回键实现自定义2秒内双击退出应用的操作 var c1c = 0; window.uexOnload = function(type){ uexWindow.setR ...
- IOS常遇问题个人收藏网址指南
代码适配Masonry使用的详细介绍: http://blog.csdn.net/majiakun1/article/details/51160339 Masonry使用注意篇: http://www ...
- centos 安装cacti监控
CentOS 6下Cacti搭建文档 安装依赖关系 yum -y install mysql-devel httpd php php-pdo php-snmp php-mysql lm_sensors ...
- jquery获取radio的值
Html代码是 <label><input type="radio" name="proofing" value="1"& ...
- mysql无法输入中文
#查看系统的环境变量 echo $LANG zh_CN.UTF-8 vim /etc/sysconfig/i18n 1 LANG="en_US.UTF-8"2 SYSFONT=&q ...
- 写入XML文件
public static void writeXMLFile(Document doc,String xmlFileName) throws IOException{ OutputFormat f ...
- webuploader限制只上传图片文件
// 如果上传的文件不为图片格式, 那么就提示"上传文件格式不正确" if (file.type!="image/jpg" && file.ty ...