Java 远程方法调用,即 Java RMI( Java Remote Method Invocation ) 。顾名思义,可以使客户机上运行的程序能够调用远程服务器上的对象(方法)。

下面主要介绍一下使用步骤:

1.定义远程接口(服务端)

远程接口定义出可以让客户远程调用的方法。

此接口必须实现 java.rmi.Remote 接口,来表示其支持远程调用;同时其中声明的所有方法,需要抛出RemoteException异常,因为远程调用的不稳定性(如网络原因等),这样可以让客户端在调用失败时进行相应的处理。

public interface DemoService extends Remote {
String sayHello() throws RemoteException;
}

2.实现远程接口(服务端)

远程接口的实现类如果想要被远程访问,可以有如下实现方式:

继承java.rmi.server.UnicastRemoteObject

public class DemoServerImpl extends UnicastRemoteObject implements DemoService{

public DemoServerImpl() throws RemoteException {
// 因为 UnicastRemoteObject 构造器抛出 RemoteException
// 所以此处只能声明一个构造器并抛出对应异常
}

@Override
public String sayHello() throws RemoteException {
return "Hello World";
}
}

如果不想继承UnicastRemoteObject类,则需要使用 UnicastRemoteObject类的静态方法exportObject(Remote obj, int port)将对象导出

其中如果端口设为 0 的话,则表示任何合适的端口都可用来监听客户连接

public class DemoServerImpl implements DemoService{

public DemoServerImpl() throws RemoteException {
UnicastRemoteObject.exportObject(this, 0);
}

@Override
public String sayHello() throws RemoteException {
return "Hello World";
}
}

这两者方法本质上是一样的,在UnicaseRemoteObject类的构造方法中,其实也是调用了exportObject方法

// UnicaseRemoteObject中的部分源码
protected UnicastRemoteObject() throws RemoteException
{
this(0);
}
// if port is zero, an anonymous port is chosen
protected UnicastRemoteObject(int port) throws RemoteException
{
this.port = port;
exportObject((Remote) this, port);
}

3.启动 RMI 注册表

注册表就像一个电话簿,启动后即可将提供的服务注册到其中,客户可以通过它查询到服务来进行调用

启动注册表有两种方法,一种是通过命令行rmiregistry来启动,另一种方式是通过LocateRegistry.createRegistry(int port)方法。

4.注册开启远程服务

注册服务共有三种方式:

  1. LocateRegistry 类的对象的 rebind() 和 lookup() 来实现绑定注册和查找远程对象的

  2. 利用命名服务 java.rmi.Naming 类的 rebind() 和 lookup() 来实现绑定注册和查找远程对象的

  3. 利用JNDI(Java Naming and Directory Interface,Java命名和目录接口) java.naming.InitialContext 类来 rebind() 和 lookup() 来实现绑定注册和查找远程对象的

其中第二种方式实际是对第一种方式的简单封装,在内部仍是调用Registry类的bind方法

// Naming 类的部分源码 (为了节省篇幅,去除了抛出异常部分)
public static void bind(String name, Remote obj) throws ...
{
ParsedNamingURL parsed = parseURL(name);
Registry registry = getRegistry(parsed);

if (obj == null)
throw new NullPointerException("cannot bind to null");

registry.bind(parsed.name, obj);
}

服务测试类:

public class ServerTest {
public static void main(String[] args) throws Exception{
String name = "rmi.service.DemoService";
// 创建服务
DemoService service = new DemoServerImpl();
// 创建本机 1099 端口上的 RMI 注册表
Registry registry1 = LocateRegistry.createRegistry(1099); /***************** 以下为注册方法一 ************/
// 将服务绑定到注册表中
registry1.bind(name, service); /***************** 以下为注册方法二 ************/
// Naming.bind(name, service); /***************** 以下为注册方法三 ************/
//Context namingContext = new InitialContext();
//namingContext.bind("rmi:" + name, service); // 此方式 name 需要以 rmi: 开头 }
}

客户端测试类:

public class ClientTest {
public static void main(String[] args) throws Exception {
String name = "rmi.service.DemoService";
/***************** 以下为查找服务方法一 ************/
// 获取注册表
Registry registry = LocateRegistry.getRegistry("localhost", 1099);
// 查找对应的服务
DemoService service = (DemoService) registry.lookup(name); /***************** 以下为查找服务方法二 ************/
// DemoService service = (DemoService) Naming.lookup(name); /***************** 以下为查找服务方法三 ************/
//Context namingContext = new InitialContext();
//DemoService service = (DemoService) namingContext.lookup("rmi:" + name); // 调用服务
System.out.println(service.sayHello());
}
}

参考文章:https://segmentfault.com/a/1190000004494341

 

RMI 使用笔记的更多相关文章

  1. Java RMI 学习笔记

    概况 功能:提供了客户辅助对象和服务辅助对象,为客户辅助对象创建和服务辅助对象形同的方法. 优点:客户不必写任何网络或I/O代码,调用远程方法就和运行在客户自己的本地JVM上对对象进行的正常方法一样. ...

  2. Java的RMI远程方法调用实现和应用

    最近在学习Dubbo,RMI是很重要的底层机制,RMI(Remote Method Invocation)远程方法调用是一种计算机之间利用远程对象互相调用实现双方通讯的一种通讯机制.使用这种机制,某一 ...

  3. Java学习笔记(十六)——Java RMI

    [前面的话] 最近过的好舒服,每天过的感觉很充实,一些生活和工作的技巧注意了就会发现,其实生活也是可以过的如此的有滋有味,满足现在的状况,并且感觉很幸福. 学习java RMI的原因是最近在使用dub ...

  4. RMI笔记

    这是<java核心技术> 第11章 分布式对象的笔记. RMI基本原理 我们使用远程方法调用是希望达到这样的目的: 可以像调用本地方法一样去调用一个远程方法. 实现远程调用的方式是 为客户 ...

  5. Neo4j图数据库管理系统开发笔记之三:构建安全的RMI Service(Server)

    RMI Server(服务端)主要包括以下功能:远程用户权限验证管理.远程服务接口实现类.Neo4j实体映射转换等.项目目录结构如下图所示: 3.2.1 远程用户权限验证管理 3.2.1.1 用户权限 ...

  6. 关于JDK高版本下RMI、LDAP+JNDI bypass的一点笔记

    1.关于RMI 只启用RMI服务时,这时候RMI客户端能够去打服务端,有两种情况,第一种就是利用服务端本地的gadget,具体要看服务端pom.xml文件 比如yso中yso工具中已经集合了很多gad ...

  7. Linux 学习笔记

    Linux学习笔记 请切换web视图查看,表格比较大,方法:视图>>web板式视图 博客园不能粘贴图片吗 http://wenku.baidu.com/view/bda1c3067fd53 ...

  8. Docker 学习笔记(CentOS 7.1)

    基本概念 Docker 包括三个基本概念 镜像(Image) 容器(Container) 仓库(Repository)理解了这三个概念,就理解了 Docker 的整个生命周期. Docker 镜像 D ...

  9. kubernetes 内网节点部署笔记(一)

    在Centos7上部署kubernetes时,碰到很多坑,特别在摸拟在内网部署时,有来自GFW的障碍,有来自Firewalld的阻塞,反正是各种不服,终于慢慢理顺了思路,自己记录一下,防止遗忘. 环境 ...

随机推荐

  1. 使用python3编写程序,生成10个随机数,每个元素的值介于1到100之间,并计算所有元素的和、平均值。

    代码如下: import random n = 0 sum = 0 while n < 10: num = random.randint(1, 100) sum = sum + num n += ...

  2. 2.5D地图系统技术方案

    1.    2.5D地图概述 1.1.    概述 2.5维地图就是根据dem.dom.dlg等数据,以及真三维模型在一定高度.视角和灯光效果,按照轴侧投影的方式生成的地图.本文以臻图信息ZTMapE ...

  3. Web架构之Nginx基础配置

    目录 1.Nginx 虚拟主机 1.1.基于域名的虚拟主机 1.2.基于端口的虚拟主机 1.3.基于IP的虚拟主机 2.Nginx include 3.Nginx 日志配置 3.1.访问日志 3.2. ...

  4. 【BIM】BIMFACE中创建矢量文本[下篇]

    背景 在上一篇文章中,我们通过THREEJS创建了矢量文本,并添加到了BIMFACE场景中,但是仅仅加入到场景中并不是我们的目的,我们的目的是把这种矢量文本加到指定的构件或者空间上,以此标识该构件或空 ...

  5. centos-Linux静态IP地址配置

    首先在VMware菜单中点击编辑-->虚拟网卡编辑器,查看NAT网段(子网掩码.网关.起止IP地址) 1.用nmcli命令配置IP地址 [root@Core ~]# nmcli connecti ...

  6. .NET实现一个简单的IOC容器

    目录 1.主要细节 2.具体示例 参考及示例代码下载 shanzm-2020年3月17日 20:06:01 1.主要细节 使用反射程序集的方式获取对象的类型 通过反射的方式获取指定类型的的所有公共属性 ...

  7. JS的3种核心设计模式

    一.单例模式 1.保证一个类仅有一个实例,并提供一个访问它的全局访问点 2.设计思路:如果存在,不创建,直接返回,不存在才创建. 在类的constructor方法里添加一个判断条件属性,并且让创建的实 ...

  8. JavaScript表单序列化的方法详解

    本文介绍下,在javascript中实现表单序列化的方法,通过实例加深理解,有需要的朋友参考下吧. 在JavaScript中,可以利用表单字段的type属性,连同name和value属性一起实现对表单 ...

  9. Jmeter中使用MD5方法

    在现在这家公司做测试的项目有用到鉴权,token的生成方式有使用到md5,具体的请求url和入参就不方便透露,讲一讲使用方法吧! 自带的Jmeter插件中是没有这个md5的所以,我们可以 (1)打开选 ...

  10. centOS6.5桌面版用不了中文输入法解决方案

    1:centos6.5中   系统->首选项->输入法中选择“使用iBus(推荐)”,点击首选输入法n遍,没有任何效果. 2.我也弄了很多种方式包括用 yum install " ...