关闭

RMI

264人阅读 评论(0) 收藏 举报
分类:
转载自: http://haolloyin.blog.51cto.com/1177454/332426/
               http://lavasoft.blog.51cto.com/62575/91679/

      RMI(即Remote Method Invoke 远程方法调用)。基本的思路可以用一个经典比方来解释:A计算机想要计算一个两个数的加法,但A自己做不了,于是叫另外一台计算机B帮忙,B有计算加法的功能,A调用它就像调用这个功能是自己的一样方便。这个就叫做远程方法调用了。实际上RMI要得以实现还得意于Java一个很重要的特性,就是Java反射机制。
      在Java中,只要一个类extends了java.rmi.Remote接口,即可成为存在于服务器端的远程对象,供客户端访问并提供一定的服务。JavaDoc描述:Remote接口用于标识其方法可以从非本地虚拟机上调用的接口。任何远程对象都必须直接或间接实现此接口。只有在“远程接口”(扩展java.rmi.Remote的接口)中指定的这些方法才可远程使用。 
      注意:extends Remote的类或者其他接口中的方法若是声明抛出了RemoteException异常,则表明该方法可被客户端远程访问调用。 
      同时,远程对象必须实现java.rmi.server.UniCastRemoteObject类,这样才能保证客户端访问获得远程对象时,该远程对象将会把自身的一个拷贝以Socket的形式传输给客户端,此时客户端所获得的这个拷贝称为“存根”,而服务器端本身已存在的远程对象则称之为“骨架”。其实此时的存根是客户端的一个代理,用于与服务器端的通信,而骨架也可认为是服务器端的一个代理,用于接收客户端的请求之后调用远程方法来响应客户端的请求。 

      下面给出一个简单的RMI 应用,其中IService接口用于声明服务器端必须提供的服务(即service()方法),ServiceImpl类是具体的服务实现类,而Server类是最终负责注册服务器远程对象,以便在服务器端存在骨架代理对象来对客户端的请求提供处理和响应。
服务器端:
package com.zero;

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

public interface IService extends Remote {
	// 声明服务器端必须提供的服务
	String deal(String content) throws RemoteException;
}
package com.zero;

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

//UnicastRemoteObject
//表明该具体服务对象可被导出给客户端
//用于导出的远程对象和获得与该远程对象通信的存根
public class ServiceImpl extends UnicastRemoteObject implements IService {

	private String name;

	/**
	 * 因为UnicastRemoteObject的构造方法抛出了RemoteException异常,因此这里默认的构造方法必须写,
	 * 必须声明抛出RemoteException异常
	 * 
	 * @throws RemoteException
	 */
	public ServiceImpl(String name) throws RemoteException {
		this.name = name;
	}

	@Override
	public String deal(String content) throws RemoteException {
		// TODO Auto-generated method stub
		return "RMI : " + this.name + " 处理----" + content;
	}

}
package com.zero;

import java.net.MalformedURLException;
import java.rmi.AlreadyBoundException;
import java.rmi.Naming;
import java.rmi.RemoteException;
import java.rmi.registry.LocateRegistry;

import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;

/**
 * 创建RMI注册表,启动RMI服务,并将远程对象注册到RMI注册表中。
 *
 */
public class Server {
	public static void main(String[] args) throws NamingException {
		try {
			// 实例化实现了IService接口的远程服务ServiceImpl对象
			IService service = new ServiceImpl("service");

			// 本地主机上的远程对象注册表Registry的实例,并指定端口为8091,
			// 这一步必不可少(Java默认端口是1099),必不可缺的一步,缺少注册表创建,则无法绑定对象到远程注册表上
			LocateRegistry.createRegistry(8091);

			// 把远程对象注册到RMI注册服务器上,并命名为myservice
			// 绑定的URL标准格式为:rmi://host:port/name

			Naming.bind("rmi://127.0.0.1:8091/myservice", service);

			System.out.println("服务器向命名表注册了1个远程服务对象!");

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

}
客户端:
package com.zero;

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

public interface IService extends Remote {
	// 声明服务器端必须提供的服务
	String deal(String content) throws RemoteException;
}
package com.zero;

import java.rmi.Naming;

import javax.naming.Context;
import javax.naming.InitialContext;

public class Client {
	public static void main(String[] args) {
		try {
			Context namingContext = new InitialContext();
			// 检索指定的对象。 即找到服务器端相对应的服务对象存根
			// 这里是根据类名找的com.zero.IService,所以服务器端和客户端的相关包必须一致
			IService service = (IService) Naming
					.lookup("rmi://localhost:8091/myservice");

			System.out.println(service.deal("你好!"));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}
运行结果:
RMI : service 处理----你好
0
0
查看评论

dubbo相关知识(六)-- java RMI框架

1、概述 在 Java 世界里,有一种技术可以实现“跨虚拟机”的调用,它就是 RMI(Remote Method Invocation,远程方法调用),通过RMI技术,某一个本地的JVM可以调用存在于另外一个JVM中的对象方法,就好像它仅仅是在调用本地JVM中某个对象方法一样。 ...
  • guchuanyun111
  • guchuanyun111
  • 2016-08-01 16:35
  • 3145

java RMI原理详解

定义 RMI(Remote Method Invocation)为远程方法调用,是允许运行在一个Java虚拟机的对象调用运行在另一个Java虚拟机上的对象的方法。 这两个虚拟机可以是运行在相同计算机上的不同进程中,也可以是运行在网络上的不同计算机中。 Java RMI:Java远程方法调...
  • xinghun_4
  • xinghun_4
  • 2015-05-17 19:16
  • 7802

RMI介绍与使用

今天在这边介绍一下Java基础中的rmi使用。其实rmi有什么样的使用场景呢?它跟webservice有什么区别呢?其实webservice主要是可以跨语言实现项目间的方法调用,而rmi只是java内部语言进行的远程方法调用。这里我们把远程这个概念用服务端表示,调用者用客户端表示。 那么首先我们先讲...
  • u014001866
  • u014001866
  • 2016-03-20 13:38
  • 3076

J2EE规范——RMI与EJB

偶然在网上看到了EJB和RMI的关系,和大家分享一下其中的奥秘 一、RMI         RMI是Java的一组拥护开发分布式应用程序的API。RMI使用Java语言接口定义了远程对象,它集合了Java序列化和Java远程方法协...
  • tr1912
  • tr1912
  • 2017-01-14 21:11
  • 574

RMI在外网不能通信的解决

前段时间写了一个全文检索服务,用的是RMI远程调用。在本机上写好后,测试ok.但一部署到服务器上就报找不到服务。在网上找了一大通: 原因如下:     RMI除了注册端口外,其通信端口是服务器随机产生的,因此不容易穿过防火墙。 现将我在网上搜索到的解...
  • wjrong_1
  • wjrong_1
  • 2015-12-12 01:01
  • 1440

浅谈RMI - 搭建一个简单的RMI程序

RMI是Remote Method Invoke的缩写,是JDK提供的一个完善的、简单易用的远程调用框架,它要求客户端和服务器端都是Java程序。下面简述RMI的基本原理:如下图所示,RMI采用代理来负责客户端和服务器之间socket通信的细节。RMI框架分别为远程对象生成了客户端代理和服务器代理,...
  • xiaoyaoyulinger
  • xiaoyaoyulinger
  • 2016-05-19 11:50
  • 2537

java远程调用rmi入门实例

RMI是Java的一组拥护开发分布式应用程序的API。RMI使用Java语言接口定义了远程对象,它集合了Java序列化和Java远程方法协议(Java Remote Method Protocol)。简单地说,这样使原先的程序在同一操作系统的方法调用,变成了不同操作系统之间程序的方法调用,由于J...
  • h348592532
  • h348592532
  • 2014-10-17 13:24
  • 2124

Java RMI 简介及其优劣势总结

今天,帮别人看UDAS配置问题时,看到采用的是RMI方式的调用,如:rmi://10.20.134.140:2299/DataServer,而且这个端口是被直接硬编码在UDAS的代码中的。既然看到了,就找了点资料了解了一下RMI,简单记录总结一下吧。 1.Java RMI 简介 RMI(Remo...
  • mingtianhaiyouwo
  • mingtianhaiyouwo
  • 2016-01-13 22:07
  • 1929

RMI穿越防火墙

RMI我接触算是比较早的了,研究生论文里阐述的项目,底层通信机制采用的就是RMI。当时还特意把RMI的规范翻译过来了,其实我上两届的师兄毕业论文几乎就是RMI的规范,当时RMI还是刚出现没有多久,作为Java的分布式对象通信技术,Corba的轻量级实现。     毕业...
  • dream8062
  • dream8062
  • 2011-12-06 17:34
  • 1699

Eclipse 里面 用RMI 插件来编写 RMI server and client的实际例子

下面是通过一个实际例子来演示如何在Eclipse中安装RMI插件来编写RMIclient/server. 1) 下载RMI 插件到eclipse (luna R4.4.1) 从下面链接下载net.genady.rmi_2.5.1.zip http://www.genady.net/rm...
  • bigtree_3721
  • bigtree_3721
  • 2016-01-31 20:18
  • 930
    个人资料
    • 访问:298594次
    • 积分:5447
    • 等级:
    • 排名:第5863名
    • 原创:203篇
    • 转载:243篇
    • 译文:0篇
    • 评论:24条