`
emptyhan
  • 浏览: 29835 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

java-rmi简单入门

    博客分类:
  • java
阅读更多
转载自 http://www.cnblogs.com/ninahan0419/archive/2009/06/25/javarmi.html

Java RMI 指的是远程方法调用 (Remote Method Invocation)。它是一种机制,能够让在某个 Java 虚拟机上的对象调用另一个 Java 虚拟机中的对象上的方法。可以用此方法调用的任何对象必须实现该远程接口。
创建Rrmote Method Invoke共需要4个对象。
通俗的说分别为: 1.远程服务器端的真正的对象,2.远程服务器端的帮助对象;3.客户端的访问对象,4.客户端的帮助对象。
其中2个帮助对象 用于封装底层的网络交互,以及保证和处理不同JVM间的使用同一个对象的完整性。
远程服务器端的帮助对象为:Skeleton      客户端的帮助对象:Stub
客户端要访问服务器上对象的方法实际上是先通过 访问 本地的帮助对象(Stub),同理要访问服务器端真正对象的方法必须要先和Skeleton 交互。所以客户端的一个用户调用服务器端的一个方法实际上是通过了2个代理对象才最后真正调用了目的方法。
Java RMI不是什么新技术(在Java1.1的时代都有了),但却是是非常重要的底层技术。
大名鼎鼎的EJB都是建立在rmi基础之上的,现在还有一些开源的远程调用组件,其底层技术也是rmi。

在大力鼓吹Web Service、SOA的时代,是不是每个应用都应该选用笨拙的Web Service组件来实现,通过对比测试后,RMI是最简单的,在一些小的应用中是最合适的。

下面通过一个简单的例子来说明RMI的原理和应用,下面这个例子是一个简单HelloWorld,但已涵盖RMI的核心应用与开发模式。

package com.test.rmi;

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

/**
 * 定义一个远程接口,必须继承Remote接口,其中需要远程调用的方法必须抛出RemoteException异常 
 *
 */
public interface IHello extends Remote {
    /** 
     * @return 返回"Hello World!"字样 
     * @throws java.rmi.RemoteException 
     */ 
    public String helloWorld() throws RemoteException; 

    /** 
     * 一个简单的业务方法,根据传入的人名返回相应的问候语 
     * @param someBodyName  人名 
     * @return 返回相应的问候语 
     * @throws java.rmi.RemoteException 
     */ 
    public String sayHelloToSomeBody(String someBodyName) throws RemoteException; 
}

package com.test.rmi;

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

public class HelloImpl extends UnicastRemoteObject implements IHello {

    /** 
     * 因为UnicastRemoteObject的构造方法抛出了RemoteException异常,
     * 因此这里默认的构造方法必须写,必须声明抛出RemoteException异常 
     * @throws RemoteException 
     */ 
    public HelloImpl() throws RemoteException { 
    }
	
	@Override
	public String helloWorld() throws RemoteException {
		return "Hello World!";
	}

	@Override
	public String sayHelloToSomeBody(String someBodyName) throws RemoteException {
		return "你好," + someBodyName + "!";
	}

}

package com.test.rmi;

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

/**
 * 创建RMI注册表,启动RMI服务,并将远程对象注册到RMI注册表中。
 */
public class RmiServer {

	public static void main(String[] args) {
        try { 
            //创建一个远程对象 
            IHello rhello = new HelloImpl(); 
            //本地主机上的远程对象注册表Registry的实例,并指定端口为8888,
            //这一步必不可少(Java默认端口是1099),必不可缺的一步,缺少注册表创建,则无法绑定对象到远程注册表上 
            LocateRegistry.createRegistry(8888); 

            //把远程对象注册到RMI注册服务器上,并命名为RHello 
            //绑定的URL标准格式为:rmi://host:port/name(其中协议名可以省略,下面两种写法都是正确的) 
            Naming.bind("rmi://localhost:8888/RHello",rhello); 
            //Naming.bind("//localhost:8888/RHello",rhello); 

            System.out.println(">>>>>INFO:远程IHello对象绑定成功!"); 
        } catch (RemoteException e) { 
            System.out.println("创建远程对象发生异常!"); 
            e.printStackTrace(); 
        } catch (AlreadyBoundException e) { 
            System.out.println("发生重复绑定对象异常!"); 
            e.printStackTrace(); 
        } catch (MalformedURLException e) { 
            System.out.println("发生URL畸形异常!"); 
            e.printStackTrace(); 
        } 
	}

}

package com.test.rmi;

import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;

/**
 * 客户端测试,在客户端调用远程对象上的远程方法,并返回结果。 
 */
public class HelloClient {

	public static void main(String[] args) {
        try { 
            //在RMI服务注册表中查找名称为RHello的对象,并调用其上的方法 
            IHello rhello =(IHello) Naming.lookup("rmi://localhost:8888/RHello"); 
            System.out.println(rhello.helloWorld()); 
            System.out.println(rhello.sayHelloToSomeBody("zhangshan1")); 
        } catch (NotBoundException e) { 
            e.printStackTrace(); 
        } catch (MalformedURLException e) { 
            e.printStackTrace(); 
        } catch (RemoteException e) { 
            e.printStackTrace();   
        } 
	}

}

可以在两台机器上测试,服务器端和客户端都需要远程接口类。
总结:
从上面的过程来看,RMI对服务器的IP地址和端口依赖很紧密,但是在开发的时候不知道将来的服务器IP和端口如何,但是客户端程序依赖这个IP和端口。
这也是RMI的局限性之一。这个问题有两种解决途径:一是通过DNS来解决,二是通过封装将IP暴露到程序代码之外。
RMI的局限性之二是RMI是Java语言的远程调用,两端的程序语言必须是Java实现,对于不同语言间的通讯可以考虑用Web Service来实现。
分享到:
评论
1 楼 wx_hello 2013-02-21  
java.rmi.ConnectException: Connection refused to host: localhost; nested exception is:
java.net.ConnectException: Connection refused: connect
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(Unknown Source)
at sun.rmi.transport.tcp.TCPChannel.createConnection(Unknown Source)
at sun.rmi.transport.tcp.TCPChannel.newConnection(Unknown Source)
at sun.rmi.server.UnicastRef.newCall(Unknown Source)
at sun.rmi.registry.RegistryImpl_Stub.lookup(Unknown Source)
at java.rmi.Naming.lookup(Unknown Source)
at com.wx.hello.rmi.HelloClient.main(HelloClient.java:12)
Caused by: java.net.ConnectException: Connection refused: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(Unknown Source)
at java.net.PlainSocketImpl.connectToAddress(Unknown Source)
at java.net.PlainSocketImpl.connect(Unknown Source)
at java.net.SocksSocketImpl.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.connect(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at java.net.Socket.<init>(Unknown Source)
at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(Unknown Source)
at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(Unknown Source)
... 7 more


报错了。。

相关推荐

    JAVA-RMI使用快速入门.doc

    【JAVA-RMI使用快速入门】 Java RMI(Remote Method Invocation,远程方法调用)是Java平台中用于构建分布式应用程序的一种核心技术。它允许Java对象在不同的Java虚拟机(JVM)之间进行交互,实现了"Write Once, ...

    《EJB-RMI入门》

    《EJB-RMI入门》是一本专注于讲解Java企业级应用开发技术的书籍,特别是针对RMI(Remote Method Invocation,远程方法调用)的使用。RMI是Java平台中用于构建分布式应用程序的关键技术,它允许Java对象在不同的Java...

    JavaRMI快速入门

    Java Remote Method Invocation(Java RMI)是Java编程语言中用于在网络间进行远程对象调用的技术。它是Java平台的标准部分,允许程序员在分布式环境中调用对象的方法,就像它们在同一台计算机上一样。Java RMI对于...

    JAVA之RMI入门

    简约而不简单的描述了RMI技术,希望对大家有所帮助。

    JAVA RMI入门教程

    【JAVA RMI入门教程】 Java Remote Method Invocation (RMI) 是Java平台中用于构建分布式应用程序的一个关键技术。RMI使得不同Java虚拟机(JVM)之间的对象可以相互通信,从而共享资源和处理能力,实现分布式计算。其...

    java Spring+RMI入门程序源代码

    通过这个 "java Spring+RMI 入门程序源代码",开发者可以学习如何在 Spring 框架中集成 RMI 技术,创建可扩展、高可用的分布式应用。项目中的 `rmiservice` 文件很可能包含了 RMI 服务端的实现,可以从中深入理解 ...

    RMI教程-入门经典

    Java RMI(Remote Method Invocation,远程方法调用)是Java平台提供的一种分布式计算技术,它允许Java对象在不同的Java虚拟机之间进行通信,仿佛这些对象都在同一台机器上。RMI是构建分布式应用程序的关键组件,...

    java RMI入门例子

    这个"java RMI入门例子"将带你深入理解RMI的工作原理和主要组件。 RMI的核心概念包括: 1. **远程接口**:这是定义远程方法的接口,通常继承自java.rmi.Remote。这些方法声明抛出java.rmi.RemoteException,表示...

    编程语言JavaRMI入门教程.pdf

    本文档是关于Java远程方法调用(Java RMI)的入门教程,适用于JDK 1.1版本。文档首次发布于1997年2月10日,由Sun Microsystems公司版权所有。Sun Microsystems公司授予用户一个全球性的、非独家的、不可转让的、无...

    java rmi demo

    java rmi入门级实例:分为三个javase项目,rmi-api(存放公共的接口和实体),rmi-server(rmi服务器端),rmi-client(rmi客户端),其中服务端和客户端都依赖rmi-api项目

    RMI 零基础入门与实例

    提供的`JAVA_RMI_实例.doc`文档可能包含了一个简单的RMI应用实例,通常包括以下部分: 1. **创建远程接口:**定义一个名为`MyRemoteInterface`的接口,声明如`sayHello()`等远程方法。 2. **实现远程接口:**创建一...

    RMI入门好例子

    这个“RMI入门好例子”旨在帮助初学者理解并实践RMI的基本原理和操作流程。 首先,RMI的核心思想是通过接口实现远程对象的透明调用。在示例中,`rmidemo`可能包含了服务器端的代码,它会定义一个接口,例如`...

    java基础教程-pdf注释版-我的入门资料

    Java语言支持面向对象编程(OOP),具有简单、安全、面向对象、稳健、多线程、解释型、高性能、分布式、动态和架构中立等特点。 3. Java语言与其他编程语言的联系:Java语言的发展受到了许多早期编程语言的影响,如...

    原创的JavaRMI项目

    这是原创的最简单的Java RMI入门项目,内含二个Eclipse项目,一是服务器端,二是客户端。非常简单,只看其中的注释就能理解(当然先要知道什么是RMI了),只供入门用。 这是用Java 1.7编辑的,如果你用的版本低,则...

    RMI入门小结

    【RMI(Remote Method Invocation)入门小结】 远程方法调用(RMI)是Java平台上的一个关键特性,它允许Java对象在不同的JVM(Java虚拟机)之间进行通信,从而实现分布式计算。RMI机制使得开发者可以像调用本地方法...

    RMI 入门学习资料

    RMI(Remote Method Invocation)是Java提供的一种用于构建分布式应用程序的机制,它允许Java对象在不同的网络环境中相互调用方法,实现了远程对象间的无缝通信。RMI是在JDK1.1版本中引入的,它是纯Java实现的,遵循...

Global site tag (gtag.js) - Google Analytics