当前位置: 首页 > news >正文

Java分布式编程:RMI机制

目录

一、RMI 核心概念

RMI 的核心组件

二、案例:用户登录验证案例

2.1 项目结构说明

服务端项目结构(IDEA)

客户端项目结构(Eclipse)

2.2 核心代码实现与解析

定义远程接口

实现远程对象(服务端逻辑)

编写 DAO 层(数据库操作)

启动 RMI 服务端

编写 RMI 客户端

2.3 运行流程与结果

 启动服务端

启动客户端


一、RMI 核心概念

        RMI(Remote Method Invocation)是Java提供的远程方法调用机制,允许在不同Java虚拟机(JVM)之间进行对象方法调用,是实现Java分布式应用的核心技术。但其仅适用于 Java 环境,无法实现与其他编程语言(如 Python、C++ 等)的跨语言分布式通信,限制了其在异构系统中的应用。

RMI 的核心组件

  • 远程接口(Remote Interface):继承java.rmi.Remote,定义可远程调用的方法(需抛出RemoteException)。
  • 远程对象(Remote Object):实现远程接口,继承UnicastRemoteObject(用于将远程对象导出,使其能够接收来自客户端的调用请求)。
  • RMI 注册表(Registry):类似 “服务注册中心”,用于存储远程对象的引用,供客户端查找。
  • 客户端(Client):通过注册表获取远程对象引用,调用其方法。

二、案例:用户登录验证案例

2.1 项目结构说明

服务端项目结构(IDEA)

客户端项目结构(Eclipse)

2.2 核心代码实现与解析

定义远程接口

        创建IData接口,继承Remote,声明可远程调用的方法(如查询信息、登录验证)。

  • 必须继承java.rmi.Remote接口
  • 所有方法必须声明抛出RemoteException
  • 接口需要同时在服务端和客户端定义(包名和类名必须一致)
package com.demo.data.interfaces;import java.rmi.Remote;
import java.rmi.RemoteException;/*** 远程接口定义* 必须继承Remote接口,所有方法必须抛出RemoteException*/
public interface IData extends Remote {// 查询系统信息public String queryMessage() throws RemoteException;// 用户登录验证public  String checkLogin(String username,String  userpwd) throws RemoteException;}

实现远程对象(服务端逻辑)

        创建UserDataImpl类,继承UnicastRemoteObject并实现IData接口,编写业务逻辑(如数据库登录验证)。

  • 继承UnicastRemoteObject:自动将对象 “导出” 为远程对象,允许客户端远程调用。
  • 构造方法必须抛出RemoteException:父类UnicastRemoteObject的构造方法会抛出该异常。
package com.demo.impl;import com.demo.dao.Dao;
import com.demo.data.interfaces.IData;import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;/*** 远程对象实现类:* 1. 继承UnicastRemoteObject(自动导出为远程对象)* 2. 实现IData接口*/
public class UserDataImpl   extends UnicastRemoteObject implements IData {// 必须声明构造方法,并抛出RemoteExceptionpublic  UserDataImpl() throws RemoteException {}@Overridepublic String queryMessage() throws RemoteException {return "RMI分布式从远程传过来的数据为:RMI、webservice、hessian、thrift、googleRPC、Dubbo";}@Overridepublic String checkLogin(String username, String userpwd) throws RemoteException {Dao dao = new Dao();// 调用Dao层验证登录(实际连接数据库)if(dao.checkLogin(username,userpwd)>0){return "登录成功";}return "登录失败";}
}

编写 DAO 层(数据库操作)

        创建Dao类,负责数据库连接与登录验证逻辑(需提前在数据库中创建jk202508数据库和t_emp表)。

package com.demo.dao;import java.sql.*;/*** DAO层:数据库操作*/
public class Dao {Connection conn;public Dao(){try {// 加载MySQL驱动Class.forName("com.mysql.cj.jdbc.Driver");// 建立数据库连接conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/jk202508", "root", "123456");} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}// 验证用户登录public  int  checkLogin(String  username,String userpwd){String  sql ="select  count(ename)  from    t_emps  where ename = ? and  epwd =?";int count = 0;try {PreparedStatement  pstmt =  this.conn.prepareStatement(sql);pstmt.setString(1,username);pstmt.setString(2,userpwd);ResultSet rs =   pstmt.executeQuery();while(rs.next()){count  = rs.getInt(1);}} catch (SQLException e) {e.printStackTrace();}finally {if(null!=conn){try {conn.close();} catch (SQLException e) {e.printStackTrace();}}}return  count;}}

启动 RMI 服务端

创建ServerRMI类,负责:

  1. 实例化远程对象。

  2. 启动 RMI 注册表(端口9200)。

  3. 将远程对象绑定到注册表,供客户端查找。

核心 API 说明:

  • LocateRegistry.createRegistry(端口号):在指定端口启动 RMI 注册表。
  • Naming.bind(url, obj):将远程对象绑定到注册表,url是客户端查找的地址。
package com.demo.serverrmi;import com.demo.data.interfaces.IData;
import com.demo.impl.UserDataImpl;import java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;/*** RMI服务端:启动服务并注册远程对象*/
public class ServerRMI {public static void main(String[] args) {try {// 1. 实例化远程对象IData dataService   = new UserDataImpl();// 2. 启动RMI注册表(端口9200)LocateRegistry.createRegistry(9200);System.out.println("RMI注册表已启动,端口:9200");// 3. 将远程对象绑定到注册表(URL格式:rmi://IP:端口/名称)Naming.bind("rmi://127.0.0.1:9200/userdatas",dataService);System.out.println("Java的RMI服务已经启动成功,等待客户端连接...");} catch (RemoteException e) {e.printStackTrace();} catch (MalformedURLException e) {e.printStackTrace();} catch (AlreadyBoundException e) {e.printStackTrace();}}
}

编写 RMI 客户端

创建Test类,作为客户端:

  1. 通过Naming.lookup()从注册表获取远程对象引用。

  2. 调用远程对象的方法(如queryMessage()checkLogin())。

核心逻辑

  • Naming.lookup(url):根据 URL 从注册表获取远程对象引用,强制转换为IData接口。
  • 调用data.queryMessage()data.checkLogin():与本地方法调用语法完全一致,RMI 会自动处理远程通信。
package com.demo.javarmiclient;import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.util.Scanner;import com.demo.data.interfaces.IData;/*** RMI客户端:调用远程对象方法*/
public class Test {// 远程对象引用(静态初始化,确保启动时就获取)static IData data = null;static {try {// 从注册表查找远程对象data = (IData) Naming.lookup("rmi://127.0.0.1:9200/userdatas");} catch (MalformedURLException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (RemoteException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (NotBoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}}// 调用远程方法:查询信息public void queryMsg() {try {String message = data.queryMessage();System.out.println("客户端远程调用服务端的结果为:" + message);} catch (RemoteException e) {// TODO Auto-generated catch blocke.printStackTrace();}}// 调用远程方法:登录验证public void checkLogin(String username, String userpwd) {try {String result = data.checkLogin(username, userpwd);System.out.println("客户端远程调用服务端登录的结果为:" + result);} catch (RemoteException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public static void main(String[] args) {Test t = new Test();
//		 t.queryMsg();System.out.println("请输入用户姓名:");Scanner s1 = new Scanner(System.in);String username = s1.next();System.out.println("请输入用户密码:");Scanner s2 = new Scanner(System.in);String userpwd = s2.next();t.checkLogin(username, userpwd);}}

2.3 运行流程与结果

        RMI 是 Java 分布式通信的 “入门级” 方案,它通过远程接口 + 远程对象 + 注册表的组合,实现了 “像调用本地方法一样调用远程方法” 的效果。本文通过 “用户登录验证” 案例,演示了 RMI 的完整开发流程:

  1. 定义远程接口(IData

  2. 实现远程对象(UserDataImpl

  3. 启动服务端并注册对象(ServerRMI

  4. 客户端查找并调用远程方法(Test

 启动服务端

启动客户端


文章转载自:

http://PLWBXA55.zsLtw.cn
http://CNKVMSi0.zsLtw.cn
http://Z8V3xuW6.zsLtw.cn
http://AZyPk5tS.zsLtw.cn
http://FxlG3cgB.zsLtw.cn
http://sAENUNdU.zsLtw.cn
http://Zsvtto3K.zsLtw.cn
http://K3TEHDa7.zsLtw.cn
http://GnyIFwBd.zsLtw.cn
http://fIEuVzIS.zsLtw.cn
http://pD5KJvUR.zsLtw.cn
http://Rfp6zj5k.zsLtw.cn
http://rN7F5IH4.zsLtw.cn
http://g64477P5.zsLtw.cn
http://63mwz87t.zsLtw.cn
http://VMpjJEUZ.zsLtw.cn
http://YQYL030Y.zsLtw.cn
http://xvAqC19N.zsLtw.cn
http://YrRszeoJ.zsLtw.cn
http://o5RVkQY6.zsLtw.cn
http://coa73AI2.zsLtw.cn
http://kjw4eNpU.zsLtw.cn
http://a2HTRtQG.zsLtw.cn
http://cet6N6Cp.zsLtw.cn
http://6CMjrkS4.zsLtw.cn
http://2B76Lj37.zsLtw.cn
http://n1VsiS63.zsLtw.cn
http://NlYxDQXV.zsLtw.cn
http://t4nphJDI.zsLtw.cn
http://0aijjTA8.zsLtw.cn
http://www.dtcms.com/a/382843.html

相关文章:

  • 5-12 WPS JS宏 Range数组规范性测试
  • MySQL 的安装、启动、连接(Windows、macOS 和 Linux)
  • (附源码)基于Spring Boot的宿舍管理系统设计
  • Mac下Python3安装
  • C++数组与字符串:从基础到实战技巧
  • 第13课:分布式Agent系统
  • Docker 容器化部署核心实战——Nginx 服务配置与正反向代理原理解析
  • 【分享】中小学教材课本 PDF 资源获取指南
  • 如何用 Git Hook 和 CI 流水线为 FastAPI 项目保驾护航?
  • 安卓旋转屏幕后如何防止数据丢失-ViewModel入门
  • STM32_05_时钟树
  • 元宇宙与体育产业:沉浸式体验重构体育全链条生态
  • LeetCode 每日一题 966. 元音拼写检查器
  • C++密码锁 2023年CSP-S认证真题 CCF信息学奥赛C++ 中小学提高组 第二轮真题解析
  • Vue3 视频播放器完整指南 – @videojs-player/vue 从入门到精通
  • 零售企业数字化转型的道、法、术:基于开源AI大模型AI智能名片S2B2C商城小程序的战略重构
  • 【编号500】(道路分类)广东路网数据广东路网分类数据(2025年)
  • 【PHP7内核剖析】-1.3 FPM
  • 网络编程之UDP广播与粘包问题
  • h3笔记:polygon
  • Unity 性能优化 之 编辑器创建资源优化( 工作流 | 场景 | 预制体)
  • 《Python Web部署应知应会》No3:Flask网站的性能优化和实时监测深度实战
  • 《嵌入式硬件(十):基于IMX6ULL的按键操作》
  • JVM默认栈大小
  • 深度学习实战指南:从神经网络基础到模型优化的完整攻略
  • 浏览器性能测试深度解析:指标、工具与优化实践
  • 【嵌入式DIY实例-ESP32篇】-3D姿态测量(Pitch, Roll, Yaw)
  • LeetCode 0966.元音拼写检查器:三个哈希表实现
  • 深入浅出 HarmonyOS 应用开发:ArkTS 声明式 UI 与状态管理最佳实践
  • 大数据处理与清洗实战:从Spark到Flink的深度优化