本文讨论的内容:
- 1、什么是RMI
- 2、RMI的作用和用途
- 3、RMI的运行步骤和实现代码
- 4、RMI优势与劣势的分析
一、什么是RMI 远程方法调用(文档描述)。客户端远程调用服务器端的方法,得到方法的结果(返回值)。这里不花多功夫解释,相信我们在进行代码的分析和运行后会了解什么是RMI。
二、RMI的作用和用途
初学RMI,它能够帮助我们查找并执行远程对象的方法。通俗地说,远程调用就象将一个class放在A机器上,然后在B机器中产生一个代理对象来调用这个class的方法。目前我认为它的作用就是,远程调用方法,实现分布式。
三、RMI的运行步骤和实现代码
1、编写服务器端要被客户端远程调用的对象的接口,这里例如是ServiceInterface。必需继承Remote接口。
package cn.netjava.ml.jdkrmi;
import java.rmi.Remote;
import java.rmi.RemoteException;
/**
* RMI调用对象接口定义
* @author ml
*
*/
public interface ServiceInterface extends Remote{
/**
* 继承于他的远程服务对象所必需实现的方法
* 所有远程服务的方法都必需声明异常
* @param object
* @return
* @throws RemoteException
*/
Object service(Object object) throws RemoteException;
}
Remote 是RMI中一个空的接口
Object service(Object object)
throws RemoteException 是我们自定义的一个方法,在将来可以被客户端远程调用,返回客户端想得到的对象,当然可以是空。这里注意必需声明RemoteException 异常。
2、编写要被远程调用对象接口的实现类
package cn.netjava.ml.jdkrmi;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
/**
* RMI服务对象接口实现,此对象将被RMI服务器导出做为远程服务对象
*
* @author ml
*
*/
public class ServiceImp extends UnicastRemoteObject implements ServiceInterface {
/**
*
*/
private static final long serialVersionUID = -2212782652822117319L;
/**
* 父类构造器
*
* @throws RemoteException
*/
protected ServiceImp() throws RemoteException {
super();
// TODO Auto-generated constructor stub
}
/**
* 客户端将要调用的方法
*/
@Override
public Object service(Object object) throws RemoteException {
// TODO Auto-generated method stub
System.out.println(object);
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return object + " " + System.currentTimeMillis();
}
}
除了继承服务对象接口外还要继承UnicastRemoteObject类。这里必须要有的一个是构造器,一个是重写service方法。构造器里面调用super()。查查源码就知道super是指UnicastRemoteObject导出了这个服务对象(serviceImp)。service方法就是将来要被客户端调用的方法,这服务器端执行。
3、编写服务启动类
package cn.netjava.ml.jdkrmi;
import java.io.IOException;
import java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;
import java.rmi.server.RMISocketFactory;
import java.rmi.server.ServerNotActiveException;
/**
* 启动RMI服务器导出服务对象
*
* @author Administrator
*
*/
public class ServiceStart {
public static void main(String[] args) {
int listenPort = 9003;
String serverIP = "localhost";
// 要导出服务对象的名字
String serverObjName = "serverObjName";
// 设置RMI服务监听端口
LocateRegistry.createRegistry(listenPort);
// 设置日志
ServiceImp.setLog(System.out);
// 创建要导出的服务对象,并绑定服务
ServiceImp remoteObj = new ServiceImp();
try {
Naming.rebind("rmi://" + serverIP + ":" + listenPort + "/"
+ serverObjName, remoteObj);
System.out.println("RMI服务启动了");
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
代码有注释,这里不多做解释了。
4、编写客户端要调用远程对象的接口
这里看起来好像不太明白。简单解释是这样的,客户端要远程调用服务器对象的方法,首先客户端必须要有要被远程调用的对象的接口。这里直接把服务器端的那个ServiceInterface复制过来就行了。有一点必须注意的是。
这个接口名以及接口所在的包名必需和服务器端一样!!这里就不贴代码了。
5、编写客户端远程调用类
package cn.netjava.ml.jdkrmi;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.Remote;
import java.rmi.RemoteException;
/**
*
* @author ml
*
*
*报名要和服务器端相同
*/
public class RMIClient {
public static void main(String[] args) {
int listenPort = 9003;
String serverIP = "localhost";
String serverObjName = "serverObjName";
try {
ServiceInterface remote = (ServiceInterface) Naming
.lookup("rmi://" + serverIP + ":" + listenPort + "/"
+ serverObjName);
for (int i = 0; i < 3; i++) {
//客户端还是要有ServiceInterface对象~~~~
Object object = remote.service("我是远程客户"+i);
System.out.println("客户端调用远程方法了");
System.out.println("远程服务应答"+object);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (RemoteException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NotBoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
6、服务器端编译桩,并把生成的桩复制在客户端的bin目录下
进入windows命令行或linux命令终端。输入rmic。有反应了吧,这就是编译桩的工具和javac类似。如果没有的话可能没有配环境变量。我们先编译生成所有类的class文件,再用cd命令进入工程的bin目录,之后使用rmic cn.netjava.ml.jdkrmi.ServiceImp 命令。
这里一定要加上包名(cn.netjava.ml.jdkrmi)。之后会生成ServiceImp_Stub.class文件,把他复制到客户端的class文件目录里就完成了。
7、分别运行服务器和客户端进行测试
四、RMI优势与劣势的分析
优势:RMI提供了java的远程方法调用,给java的分布式带来了方便。
劣势:个人认为RMI用的还是比较少的。
1、RMI仅仅是JAVA的实现,如果服务器是java,客户端是C++就不行了
2、RMI基于C/S模型 比不上基于B/S模型的其他框架实现如(Hessian和Burlap)。
分享到:
相关推荐
### 实例教程J2EE编程起步 #### 一、引言 随着互联网技术的发展和企业级应用需求的增长,Java 2 Platform, Enterprise Edition (J2EE) 成为了一种广泛应用于构建可伸缩且高性能的企业应用程序的技术框架。本文旨在...
《零碳城市手册》是一部旨在指导全球城市实现零碳排放目标的专业手册,由落基山研究所(Rocky Mountain ...尽管手册中提供的建议无法立即实现零碳目标,但它们被视为经济有效的转型起步,是向零碳未来迈进的关键一步。
掌握Spring Boot的起步依赖、自动配置以及Spring Cloud的相关组件如Eureka、Zuul、Hystrix等,对于构建分布式系统至关重要。 分布式数据存储和缓存也是重要一环。例如,Redis和Memcached提供高性能的键值存储,而...
序列化对于数据传输、持久存储、以及实现 RMI(远程方法调用)等跨进程通信场景非常有用。 问题 7:Java 中的集合框架有哪些主要部分?它们各自的作用是什么? 答案:Java 集合框架主要包括接口(如 List、Set、Map...
SpringBoot的核心特性包括自动配置、内嵌Servlet容器(如Tomcat)、起步依赖以及Actuator监控。自动配置使得开发者无需编写大量XML配置文件,而是通过"约定优于配置"的原则,快速构建应用程序。内嵌的Servlet容器则...
Spring Boot通过自动配置和起步依赖让创建独立的Spring应用变得简单,而Spring Cloud则为分布式系统中的服务发现、配置中心、负载均衡、熔断器等提供了统一的API和实现。 通过阅读《精通Spring(清晰书签版)》,读者...
通过自动配置和“起步依赖”特性,SpringBoot使得开发者可以快速启动并运行一个包含所有必需组件(如数据源、MVC、安全等)的应用。在本项目中,SpringBoot作为基础框架,提供了便捷的依赖管理和快速启动服务的能力...
Quartz 起步 内容提要:本章对 Quartz 框架一个快速的入门介绍,同时也大略指导你从哪里下载,构建和安装这个框架 第三章. Hello Quartz (第一部分) 内容提要:建立 Hello Quartz 工程,并创建一个 Quartz Job 类...
Spring 支持与各种技术的优雅集成,如Hibernate、JDO、TopLink、EJB、RMI、JNDI、JMS、Web服务和Struts等,为开发者提供了便利的接口和工具。 【模块化结构】 Spring 框架由多个模块组成,包括核心容器(Core ...
Spring Boot是为简化Spring应用程序开发而生的框架,它通过自动配置、起步依赖和命令行接口(CLI)等特性大大降低了项目的初始化和配置复杂度。Spring Boot允许开发者快速创建独立运行的应用,并内置了Tomcat或Jetty...
- **特性**:自动配置、内嵌 Servlet 容器(如 Tomcat)、提供起步依赖、健康检查、运行时指标监控等。 - **应用创建**:通过 `@SpringBootApplication` 注解启动 Spring Boot 应用,包含 `@...
Spring Boot的核心特性包括起步依赖、嵌入式Web服务器、自动配置和Actuator等,这些都极大地提高了开发效率。 接着,我们来看Dubbo。Dubbo是一个高性能的RPC(Remote Procedure Call)框架,其核心设计目标是提供轻...
11.3.2从pitchfork起步 11.3.3通过注释注入资源 11.3.4使用注释声明拦截器 11.4小结 第12章访问企业服务 12.1从jndi中获取对象 12.1.1使用传统的jndi 12.1.2注入jndi对象 12.1.3在spring2中注入jndi对象 ...
11.3.2 从Pitchfork起步 11.3.3 通过注释注入资源 11.3.4 使用注释声明拦截器 11.4 小结 第12章 访问企业服务 12.1 从JNDI中获取对象 12.1.1 使用传统的JNDI 12.1.2 注入JNDI对象 12.1.3 在Spring 2中注入...
11.3.2 从Pitchfork起步 11.3.3 通过注释注入资源 11.3.4 使用注释声明拦截器 11.4 小结 第12章 访问企业服务 12.1 从JNDI中获取对象 12.1.1 使用传统的JNDI 12.1.2 注入JNDI对象 12.1.3 在Spring 2中注入...
1. **简化Spring配置**:通过自动配置和起步依赖,极大地减少了XML配置。 2. **内嵌Web服务器**:内建Tomcat或Jetty等服务器,无需额外部署。 3. **命令行界面**:提供了方便的命令行工具,简化项目创建和运行。 4. ...
- **连接JMX服务器**:介绍如何通过JMX控制台、RMI协议或命令行工具访问和管理JBoss服务器。 #### 使用JMX作为微内核 - **启动过程**:解析服务器启动时JMX微内核的工作流程。 - **MBean服务**:详细阐述JBoss ...