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. python切片使用方法(超详细)

    #切片:就是根据一个下标范围来获取一部分数据,切片通常结合字符串,列表,元组使用 # 为什么使用切片?因为下标只能获取一个数据,所以想要获取字符串或者列表当中一部分数据需要用切片. # 切片的语法格式 ...

  2. SSL/TLS 协议运行机制概述(二)

    SSL/TLS 协议运行机制概述(二) 在SSL/TLS 协议运行机制概述(一)中介绍了TLS 1.2 的运行机制,现在我们来看年 TLS 1.3 的运行机制.会涉及到SSL/TLS 协议运行机制概述 ...

  3. vue2.0:项目开始,首页入门(main.js,App.vue,importfrom)

    对main.js App.vue 等进行操作: 但是这就出现了一个问题:什么是main.js,他主要干什么用的?App.vue又是干什么用的?main.js 里面的import from又在干嘛?ne ...

  4. go入门二

    一.流程控制 1.选择结构 if-else: package main import ( "io/ioutil" "fmt" ) func main(){ co ...

  5. centos7安装部署opentsdb2.4.0

    写在前面 安装HBase 在HBase中创建表结构 安装配置并启动opentsdb 写在前面 最近因为项目需要在读opentsdb的一部分源码,后面会做个小结分享出来.本人是不大喜欢写这种安装部署的文 ...

  6. 当AI遇上K8S:使用Rancher安装机器学习必备工具JupyterHub

    Jupyter Notebook是用于科学数据分析的利器,JupyterHub可以在服务器环境下为多个用户托管Jupyter运行环境.本文将详细介绍如何使用Rancher安装JupyterHub来为数 ...

  7. vue-element框架通过blob进行后端token权限验证下载

    在项目中,后端要求下载时要进行后端的权限验证,发现a链接进行直接下载无法满足这个需求,只能通过blob对象来进行下载操作,翻阅大量资料最后实现该功能.以下是我个人的理解,如有不足,请各位大佬多指教 / ...

  8. Shell中的参数传递

    原文链接 我们先来定义一个方法 function methodName() { paramName1=$1 paramName2=$2 paramName3=$3 # 依此类推,参数是从1开始标号,而 ...

  9. Python3 整数

    imag定义:返回整数的复数形式的虚部(返回整数).格式:intobject.imag real定义:返回整数的复数形式的实部(返回整数).格式:intobject.real conjugate()定 ...

  10. 安装SQL Server 2008R2 报错“此计算机上安装了 Microsoft Visual Studio 2008 的早期版本”解决方法

    安装SQL Server 2008 R2报错“此计算机上安装了 Microsoft Visual Studio 2008 的早期版本,请在安装 SQL Server 2008 前将 VS2008 升级 ...