RPC(6):RMI实现RPC

1RMI简介

RMI(Remote Method Invocation) 远程方法调用。

RMI是从JDK1.2推出的功能,它可以实现在一个Java应用中可以像调用本地方法一样调用另一个服务器中Java应用(JVM)中的内容。

RMI 是Java语言的远程调用,无法实现跨语言。

2 执行流程

Registry(注册表)是放置所有服务器对象的命名空间。 每次服务端创建一个对象时,它都会使用bind()或rebind()方法注册该对象。 这些是使用称为绑定名称的唯一名称注册的。

要调用远程对象,客户端需要该对象的引用。即通过服务端绑定的名称从注册表中获取对象(lookup()方法)。

3 API介绍

3.1 Remote

java.rmi.Remote 定义了此接口为远程调用接口。如果接口被外部调用,需要继承此接口。

3.2 RemoteException

java.rmi.RemoteException

继承了Remote接口的接口中,如果方法是允许被远程调用的,需要抛出此异常。

3.3 UnicastRemoteObject

java.rmi.server.UnicastRemoteObject

此类实现了Remote接口和Serializable接口。

自定义接口实现类除了实现自定义接口还需要继承此类。

3.4 LocateRegistry

java.rmi.registry.LocateRegistry

可以通过LocateRegistry在本机上创建Registry,通过特定的端口就可以访问这个Registry。

3.5 Naming

java.rmi.Naming

Naming定义了发布内容可访问RMI名称。也是通过Naming获取到指定的远程方法。

4 代码实现

4.1 创建RMI接口

编写接口文件

package com.example.demo;

import java.rmi.Remote;
import java.rmi.RemoteException;

// 定义一个远程服务接口。RMI强制要求,必须是Remote接口的实现。
public interface FirstInterface extends Remote {
    // RMI强制要求,所有的远程服务方法,必须抛出RemoteException。
    String first(String name) throws RemoteException;
}

4.2 创建服务端

引入pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>rmi_rpc</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>rmi_rpc_server</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>rmi_rpc_api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>

编写远程服务接口

package com.example.demo.impl;

import com.example.demo.FirstInterface;

import java.rmi.Remote;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

// 实现远程服务接口。 所有的远程服务实现,必须是Remote接口直接或间接实现类。
// 如果不会创建基于RMI的服务标准实现,可以继承UnicastRemoteObject类型。
// RMI强制要求,所有的方法必须抛出RemoteException,包括构造方法。
public class FirstRMIImpl extends UnicastRemoteObject implements FirstInterface, Remote {
    public FirstRMIImpl() throws RemoteException {
        super();
    }

    public String first(String name) throws RemoteException {
        System.out.println("客户端请求参数是:" + name);
        return "你好," + name;
    }
}

创建启动类,将服务注册到Registry上

package com.example.demo;

import com.example.demo.impl.FirstRMIImpl;

import java.rmi.Naming;
import java.rmi.registry.LocateRegistry;

// 主方法,创建一个服务实现对象,提供服务,并注册到Registry上。
// RMI的Registry在创建的时候,会自动启动一个子线程,并升级为守护线程(服务线程|精灵线程)。提供持久的服务。
public class MainClass {
    public static void main(String[] args) {
        try {
            System.out.println("服务器启动中...");
            // 创建服务对象
            FirstInterface first = new FirstRMIImpl();
            // 注册到Registry(注册中心)上。
            LocateRegistry.createRegistry(9999);
            // 绑定一个服务到注册中心。提供命名,格式为:rmi://ip:port/别名
            // 如果服务重复,抛出异常。 重复的定义是命名冲突。
            // Naming.bind("rmi://localhost:9999/first", first);
            // 重新绑定一个服务到自注册中心。 和bind的区别是,命名冲突,直接覆盖。
            Naming.rebind("rmi://localhost:9999/first", first);

            System.out.println("服务器启动完毕!");
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

启动服务,结果如下:

4.3 创建客户端

引入pom依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>rmi_rpc</artifactId>
        <groupId>org.example</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>rmi_rpc_client</artifactId>
    <dependencies>
        <dependency>
            <groupId>org.example</groupId>
            <artifactId>rmi_rpc_api</artifactId>
            <version>1.0-SNAPSHOT</version>
        </dependency>
    </dependencies>

</project>

编写服务调用RMI的RPC服务

package com.example.demo;

import java.rmi.Naming;

// 客户端主方法
public class ClientMainClass {
    public static void main(String[] args) {
        // 代理对象的创建。
        FirstInterface first = null;
        try{
            // 使用lookup找服务。通过名字找服务,并自动创建代理对象。
            // 类型是Object,对象一定是Proxy的子类型,且一定实现了服务接口。
            first = (FirstInterface) Naming.lookup("rmi://localhost:9999/first");

            System.out.println("对象的类型是:" + first.getClass().getName());
            String result = first.first("S106,今天课程讲不完了");
            System.out.println(result);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

启动服务,结果如下:

这时候查看服务端程序,会显示连接申请的服务,效果如下:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/270709.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

小程序真机如何清除订阅数据

在做小程序订阅消息开发的过程中发现&#xff0c;真机上如果是选择了‘总是保持以上选择’&#xff0c;一旦用户授权后&#xff0c;后面就不会再弹出申请改订阅消息的授权弹窗&#xff0c;这对于开发过程中是很不方便的。 曾试过清除缓存&#xff0c;重进小程序也不能清除掉 解…

爬虫反爬之代码混淆,特殊编码,表情编码

不知道你是否见过这样的代码&#xff0c;完全看不懂。 大家好&#xff0c;这一集我们来看一下前端反爬的代码混淆&#xff0c;一般啊我们自己写的前端代码都是直接上传公开的&#xff0c;如果用的不是框架打包出来的代码&#xff0c;就是自己写的js&#xff0c;html文件没有经过…

T-Dongle-S3开发笔记——创建工程

创建Hello world工程 打开命令面板 方法1&#xff1a;查看->命令面板 方法2&#xff1a;按F1 选择ESP-IDF:展示示例项目 创建helloworld 选择串口 选择芯片 至此可以编译下载运行了 运行后打印的信息显示flash只有2M。但是板子上电flash是W25Q32 4MB的吗 16M-bit

SPFA算法总结

知识概览 SPFA算法是Bellman_Ford算法的优化。时间复杂度一般是O(m)&#xff0c;最坏时间复杂度是O(nm)&#xff08;遇到网格图、菊花图&#xff09;&#xff0c;其中n是点数&#xff0c;m是边数。SPFA算法其实是单源最短路限制最小的算法&#xff0c;只要图中没有负环&#xf…

Mongodb基础介绍与应用场景

NoSql 解决方案第二种 Mongodb MongoDB 是一款开源 高性能 无模式的文档型数据库 当然 它是NoSql数据库中的一种 是最像关系型数据库的 非关系型数据库 首先 最需要注意的是 无模式的文档型数据库 这个需要后面我们看到它的数据才能明白 其次是 最像关系型数据库的非关系型数据…

通过three.js玩转车展项目

1.项目搭建 1.1 创建文件夹 mkdir 文件名1.2 初始化package.json npm init -y1.3 安装打包工具并配置相关依赖 npm i parcel -d在package.json中打包路径和指令 1.4 安装three.js npm i three -d2.项目搭建 2.1 新建index.html&#xff0c;并再index.html引入car.js,在…

2023版本QT学习记录 -6- UDP通信之UDP接收端

———————UDP接收端——————— &#x1f384;动图演示 &#x1f384;发送端通信步骤思维导图 &#x1f384;添加组件 QT core gui network&#x1f384;添加头文件 #include "qudpsocket.h"&#x1f384;创建接收对象 QUdpSocket *recvsocket;&…

在VSCode中使用Git教程

文章目录 提交代码操作分支提交远程库拉取代码参考 介绍一下如何在VSCode中使用Git 首先在VSCode中打开一个项目 打开项目后, 点击下图按钮, 可以引入Git 提交代码 点击 &#xff1b;相当于git add. 下面两张图, 第一张表示改文件后的号, 只会add本文件. 第二张图表示这段时…

Jenkins的邮箱配置和插件下载

启动&#xff1a;java -jar jenkins.war 一定在jenkins.war的目录下 进入cmd命令 浏览器输入网址&#xff1a;http://localhost:8080/login?from%2F 账号&#xff1a;admin 密码&#xff1a;123456 安装插件&#xff1a; 插件更新后重启下 配置邮箱账号&#xff1a; 3…

关于PSINS中涉及到的地球参数更新

地球参数相关的更新函数 void CEarth::Update(const CVect3 &pos, const CVect3 &vn, int isMemsgrade) 用到位置以及速度 那么位置和速度用的哪个时刻的&#xff1f; 假如设计算周期为[T,2T] &#xff1b; 解算时刻为2T时刻&#xff0c;那么地球参数用的是哪一时刻的…

【自然语言处理】用Python从文本中删除个人信息-第二部分

自我介绍 做一个简单介绍&#xff0c;酒架年近48 &#xff0c;有20多年IT工作经历&#xff0c;目前在一家500强做企业架构&#xff0e;因为工作需要&#xff0c;另外也因为兴趣涉猎比较广&#xff0c;为了自己学习建立了三个博客&#xff0c;分别是【全球IT瞭望】&#xff0c;【…

canvas基础教学

Canvas <canvas>是一个可以使用脚本&#xff08;通常是JavaScript&#xff09;来绘制图形的HTML元素&#xff0c;例如&#xff0c;它可以用于绘制图表、制作图片构图或者制作简单的动画。 本篇博客从一些就基础开始&#xff0c;描述了如何使用<canvas>元素来绘制…

Java基础回顾——多线程

文章目录 介绍创建新线程线程的状态中断线程守护线程线程同步同步方法 死锁wait和notifyReentrantLockconditionReadWriteLockStampedLockSemaphore线程池FutureCompletableFuture 介绍 计算机中&#xff0c;一个任务称为一个进程&#xff0c;某些进程内部还需要同时执行多个子…

excel统计分析——K-S正态性检验

参考资料&#xff1a; 马兴华,张晋昕.数值变量正态性检验常用方法的对比[J].循证医学,2014,14(02):123-128 统计推断——正态性检验&#xff08;图形方法、偏度和峰度、统计&#xff08;拟合优度&#xff09;检验&#xff09;_sm.distributions.ecdf-CSDN博客 K-S检验法判断…

一文详解SpringBoot 定时任务(cron表达式)

IDE&#xff1a;IntelliJ IDEA 2022.2.3 x64 操作系统&#xff1a;win10 x64 位 家庭版 JDK: 1.8 文章目录 一、如何开启一个SpringBoot定时任务&#xff1f;二、cron表达式详解2.1 语法格式2.2 符号解析2,2.1 通用符号: , - * /2.2.2 专有符号&#xff1a;&#xff1f;L w # c…

Linux操作系统——进程(四)进程切换与命令行参数

进程切换 概念引入 下面我们先了解几个概念&#xff1a; 竞争性: 系统进程数目众多&#xff0c;而CPU资源只有少量&#xff0c;甚至1个&#xff0c;所以进程之间是具有竞争属性的。为了高效完成任务&#xff0c;更合理竞争相关资源&#xff0c;便具有了优先级 独立性: 多进程…

关于Smartbi登录代码逻辑漏洞的动态情报

一、基本内容 近日&#xff0c;思迈特软件核查发现存在“登录代码逻辑漏洞”问题&#xff0c;重点影响范围涉及Smartbi V9及其以上版本。该漏洞可能导致攻击者利用逻辑缺陷对目标系统进行攻击&#xff0c;造成敏感信息泄露和远程代码执行的风险。 二、相关发声情况 Smartbi是…

科技巨头的选择:为何不跟风用钉钉和企业微信?

引言 大家好&#xff0c;我是你们的小米&#xff01;今天&#xff0c;我想和大家聊一聊一个很有趣的话题——为什么大厂不同钉钉、企业微信等软件而自主研发IM&#xff08;即时通讯&#xff09;呢&#xff1f;难道这些明星产品还有什么不足之处&#xff1f;让我们一起揭开这个…

lv13 环境搭建之内核编译 4

一、开发板运行Linux 1. 网线连接开发板和主机 2. ubuntu下拷贝uImage、exynos4412-fs4412.dtb两个文件到/tftpboot目录下cd ~/fs4412cp uImage exynos4412-fs4412.dtb /tftpboot 3. rootfs.tar.xz解压到/opt/4412sudo tar xvf rootfs.tar.xz -C /opt/4412sudo chmod 777 /opt…

项目中关于地理位置相关需求的实现思路

实现思路&#xff1a;通过Redis中的GEO数据结构进行实现 一、GEO命令&#xff1a; 1.命令示例&#xff1a; GEOADD g1 116.378248 39.865275 bjn 116.42803 39.903738 bjz 116.322287 39.893729 bjx输出结果&#xff1a; 2.计算bjx&#xff08;北京西站&#xff09;到bjn&…