- 浏览: 101983 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
liusong6196:
...
Oracle连接查询,子查询(相关子查询,嵌套子查询) -
happybine:
以前从来没有觉得,有必要使用团队协作的工具,平时用邮件+QQ, ...
团队协作平台
【转自:http://blog.csdn.net/lethorld/article/details/7089374#】
1.RMI和Java Remote Method Invocation
在讨论RMI之前,我们先看看网站的架构。典型的网站有一个服务提供商(Web Server),多个服务使用者(Web
Client)。网站使用的是浏览器(Browser)作为客户端,也就是所说的BS架构(Browser-Server)。还有一种不是使用浏览器作为客户端的,比如说即时聊天工具(QQ、MSN)等,它们需要你在本地安装相应的客户端程序后才能运行,这就是所说的CS架构(Client-Server)。CS架构和BS架构相比较,BS的优势在于它能够有很好的移植和兼容性(只要你本地安装了浏览器,原则上你就能使用我的系统);而对于CS架构,个人觉得它的优势在于可操作性(客户端完全由自己开发,可以想怎么写就怎么写,完全不需要受到浏览器的约束)。
现在我们说说所谓的RMI,RMI全称为Remote Method
Invocation,中文翻译为远程方法调用。指的是从本地调用服务器上的一组方法,服务器根据提交的信息(方法名、方法携带参数)计算得到结果、并将结果返回给调用者。Java
Remote Method
Invocation指的是在Java上实现上述机制。RMI可以理解成一种思想,一种架构,而JRMI则是这种思想或者架构的Java版本的实现。
好的机制需要屏蔽底层的实现细节。对于RMI的实现,需要做到:调用远程对象(Remote Object)和调用本地对象(Local
Object)对于调用者来说没有任何区别。基于这个出发点,我们看看本地调用如何实现。
2.1 调用本地对象
首先我们需要定义一个Java类,该类有一个方法localCall。package com.ztesoft.provisioning.local; /** * 本地对象,用于被调用 * @author Lethorld * */ public class LocalObject { /** * 本地调用,用于测试 * @param arg 入参 * @return 返回 */ public String localCall(String arg) { // TODO : do something. return arg; } }然后,我们写一个类用于调用这个本地对象。package com.ztesoft.provisioning.local; /** * 本地调用者 * @author Lethorld * */ public class LocalInvoker { /** * 主函数 * @param args 入参 */ public static void main(String[] args) { LocalObject object = new LocalObject(); String retn = object.localCall("Hello"); System.out.println(retn); } }这样我们便完成了本地的一次对象调用。我们的运行main函数后,主程序会new一个LocalObject对象,并且调用该对象的localCall方法。localCall方法根据入参"Hello",返回相应的返回值。这里面没有做处理,所以返回的是Hello。OK,这段代码应该是所有只要稍微懂一点Java的人都能够看明白,并且很轻松地写出来的。那么,对于Java的远程调用,也就是上面所说的RMI,是否可以简单的把所有的local改成remote就OK了呢?答案是否定的。2.2 定义与实现分离
要实现远程调用,首先必须考虑的是如何将方法的定义和方法的实现分离开。如果方法定义与实现不能相互分离,那么我们怎么能够将方法的实现放到服务器端,而仅仅在客户端上保存一个方法的声明呢?对于Java,要完成将定义与实现相分离的任务,我们自然而然地想到了接口(interface)这个工具。请看百度百科中对于Java接口的描述:“Java中的接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,因此这些方法可以在不同的地方被不同的类实现,而这些实现可以具有不同的行为(功能)。”你看,这难道不就是我们想要的所谓的定义与实现相分离的特性吗?好吧,下面我们用接口来重写上面的例子。首先我们定以接口,接口的定义这里不赘述,也不属于本文准备详细阐述的内容。这个接口的名字叫ILocalObject,它有一个方法的声明叫localCall。注意localCall只是一个声明,它没有显示它将会如何实现localCall这个操作。然后我们定义一个类LocalObjectImpl,该类实现了接口ILocalObject。方法localCall和2.1中介绍的完全一样。package com.ztesoft.provisioning.local; /** * 本地调用接口 * @author Lethorld * */ public interface ILocalObject { /** * 本地调用,用于测试 * @param arg 入参 * @return 返回 */ public String localCall(String arg); }
- package com.ztesoft.provisioning.local.impl;
- import com.ztesoft.provisioning.local.ILocalObject;
- /**
- * 接口的实现类
- * @author Lethorld
- *
- */
- public class LocalObjectImpl implements ILocalObject {
- public String localCall(String arg) {
- // TODO : do something.
- return arg;
- }
- }
package com.ztesoft.provisioning.local.impl; import com.ztesoft.provisioning.local.ILocalObject; /** * 接口的实现类 * @author Lethorld * */ public class LocalObjectImpl implements ILocalObject { public String localCall(String arg) { // TODO : do something. return arg; } }现在我们要改一下我们的主函数,用接口的方式完成对方法的调用。下面代码的17行,我们定义了一个接口对象object,它指向一个实现了该接口的类LocalObjectImpl的实例。package com.ztesoft.provisioning.local; import com.ztesoft.provisioning.local.impl.LocalObjectImpl; /** * 本地调用者 * @author Lethorld * */ public class LocalInvoker { /** * 主函数 * @param args 入参 */ public static void main(String[] args) { ILocalObject object = new LocalObjectImpl(); String retn = object.localCall("Hello"); System.out.println(retn); } }2.3 万事俱备!让我们开始向RMI进发。
有了2.1和2.2的铺垫,现在我们可以尝试写一个由JRMI实现的远程调用的程序了。首先,我们定义一个接口,该接口要继承自Remote接口。Remote接口在jdk中的解释为:“用于标识其方法可以从非本地虚拟机上调用的接口。”其实原理很简单,我们要使用远程调用的特性,那么注定我们的类和简单的本地类之间的处理是不完全一样的。比如说:怎么远程通信?怎么序列化(反序列化)入参、返回值?对于这些差异的处理,要么我们用户自己实现,要么丢给RMI,由RMI框架帮我们实现。当然,作为用户,我们不希望每次写个远程调用都去处理这些共性的东西。于是,RMI框架抽象出来一个Remote接口。这样,对于Java程序来说,凡是遇到继承自Remote的接口,Java编译器就知道这个类可能会被远程调用了。其二,所有的远程调用的接口的方法声明中,必须含有RemoteException的声明。从JDK文档中可以看出来,RemoteException是继承自IOException。这是什么意思呢?因为我们远程调用是通过网络实现的,所以对于服务器上的异常,客户端可以统一认为是IO读写异常。这也就不难理解为什么RemoteException会被定义成IOException的子类了。这里的处理个人理解可能有点泛化的意味在里面。远程调用,在服务器上(或者在通讯过程中)可能会发生异常的错误,这点所有人都可以保证。而反过来说,没有人可以保证远程调用,在服务器上(或者在通讯过程中)永远不发生错误。既然这样,那我们就规定:所有继承Remote的接口的方法声明中,必须含有RemoteException的声明。下面是一个继承自Remote接口的接口,接口取名为IRemoteTest。IRemoteTest内部有个remoteTest的方法的声明。这个方法接受一个String类型的入参,返回值的类型也是String的。同时,它需要申明可能抛出RemoteException异常。package com.ztesoft.provisioning.rmiserver; import java.rmi.Remote; import java.rmi.RemoteException; /** * 远程调用RMI,定义的接口 * @author Lethorld * Remote 接口用于标识其方法可以从非本地虚拟机上调用的接口。 * 任何远程对象都必须直接或间接实现此接口。只有在“远程接口” *(扩展 java.rmi.Remote 的接口)中指定的这些方法才可远程使用。 * 实现类可以实现任意数量的远程接口,并且可以扩展其他远程实现类。 * RMI 提供一些远程对象实现可以扩展的有用类,这些类便于远程对象创建。 * 这些类是 java.rmi.server.UnicastRemoteObject * 和 java.rmi.activation.Activatable。 */ public interface IRemoteTest extends Remote{ public String remoteTest(String name) throws RemoteException; }接口定义好了,我们可以先把客户端的调用程序写完(接口存在的好处之一就是在不知道方法如何实现的前提下,我们同样可以完成对该方法调用的后续操作)。对于2.2中的调用,我们用一句ILocalObject object = new LocalObjectImpl();便可以实现创建一个LocalObjectImpl对象,并把这个对象赋给ILocalObject接口的任务。但是远程调用不行,因为你无法确切地知道远程服务器上的对象的名称(它并不是你本地的某个java类,它不受你的管束)。我们需要一个新的机制可以帮助我们获得远程对象的引用。这部分的工作有类Naming类实现。JDK中对该类的描述为:“Naming
类提供在对象注册表中存储和获得远程对远程对象引用的方法。”那么如何去定位一个远程对象呢?换句话说,我们如何唯一标识一个远程对象?让我们回到通常的WEB程序来看看究竟该如何处理。通常,我们要访问某一个网站,我们会在浏览器中输入网址。比如我们要访问csdn网站,我们可以输入http://www.csdn.net,点击确定,于是我们就可以浏览csdn的主页了。同样,我们还可以输入http://117.79.93.196来访问csdn主页。一般情况下,一个网站的地址会是这样的结构:http://ip:port。http://标志协议名,ip:port是典型的tcp地址。这样我们便能定位到某台机器上的某个特定的发布了的程序了。同理在浏览器中输入http://write.blog.csdn.net/postedit/7089374,你便会进入csdn博客的某篇文章(其实就是本文啦),也就是能访问到csdn网站的某个子资源。于是,我们可以认为,对于web应用http://ip:port/sub1/subsub1/...可以定位一个唯一的资源。对于RMI,其实貌似也是这么做的,只不过RMI不是HTTP,所以不用HTTP://开头;RMI貌似也不需要使用sub1/subsub1这样繁杂的子层嵌套结构。故同理:一个rmi://ip:port/name可以唯一定位一个RMI服务器上的发布了的对象。那么事实是不是这样呢?请看JDK关于Naming类的介绍,你会惊奇的发现,世界上的事,那都是想通的~
那么,剩下的就太简单了:package test.com.ztesoft.zsmart.bss.provisioning.serviceActivation; import java.net.MalformedURLException; import java.rmi.Naming; import java.rmi.NotBoundException; import java.rmi.RemoteException; import com.ztesoft.provisioning.rmiserver.IRemoteTest; public class RmiSynCallTest { public static void main(String[] args) throws RemoteException, MalformedURLException, NotBoundException { String url = "rmi://localhost:9527/rmitest"; IRemoteTest test = (IRemoteTest)Naming.lookup(url); System.out.println(test.remoteTest("Lethorld")); } }
发表评论
-
使用Log4j、ActiveMQ和Spring实现异步日志
2014-10-23 16:16 818英文原文:Asynchronous logging usin ... -
JBoss Tattletale 简介
2013-01-09 18:19 1244Tattletale1可以帮助你分析你的项目中组件之 ... -
ThreadLocal
2012-11-25 22:51 746【汇总多个博文】 首先,ThreadLocal 不是用来解决 ... -
Java Thread 多线程理论
2012-11-25 22:34 3401Java Thread 多线程 介绍 线程的概述 线 ... -
JDK1.5/1.6/1.7之新特性总结
2012-11-12 12:13 871开发过程中接触到了从jdk1.5---jdk1.7的使用 ... -
Java 7 的新特性一览表
2012-11-12 11:19 737【转自:http://www.oschi ... -
Java NIO简介
2012-10-23 22:33 731【引自:http://hbzwt.iteye.com/b ... -
JAVA NIO 简介
2012-10-23 22:28 712【引自:http://www.iteye.com/to ... -
Java程序员面试中的多线程问题
2012-05-29 17:07 801Java程序员面试中的多线程问题 很多核心Java面试题来源 ... -
关于 23 种设计模式的有趣见解
2012-05-29 16:42 682在网络上流畅很广的一 ...
相关推荐
远程方法调用(Remote Method Invocation,RMI)是Java平台中一种用于分布式计算的技术,它允许Java对象在不同的 JVM(Java虚拟机)之间调用方法,仿佛这些对象都在同一个JVM中一样。RMI是Java EE(现在被称为...
Java远程调用(Remote Method Invocation,RMI)是Java平台中一种重要的分布式计算技术,它允许在不同网络环境中的Java对象之间进行透明的交互。在本文中,我们将深入探讨三种不同的RMI实现方法:原始方式、Spring...
Java RMI(Remote Method Invocation)是Java平台提供的一种用于实现远程对象交互的技术。它允许一个Java对象调用另一个在不同 JVM(Java Virtual Machine)中的对象的方法,仿佛它们是在同一个进程中运行一样。本...
JAVA远程调用RMI与应用 一、RMI(Remote Method Invocation)概念解析 RMI,即远程方法调用,是Java平台提供的分布式计算模型,它允许Java对象跨网络进行方法调用,如同本地调用一样。RMI的实现基于Java的面向对象...
Remote Method Invocation是一种机制,能够让在某个 Java 虚拟机上的对象调用另一个 Java 虚拟机中的对象上的方法。 编写一个RMI的步骤 定义一个远程接口,此接口需要继承java.rmi.Remote 开发远程接口的实现类 创建...
### Remote Method Invocation (RMI) – 远程方法调用详解 #### 一、RMI 概述 **远程方法调用**(Remote Method Invocation, RMI)是Java平台中的一个核心概念和技术,它允许开发者创建分布式应用,在这些应用中,...
Java RMI(Remote Method Invocation,远程方法调用)是Java平台提供的一种用于在不同网络节点上的Java对象之间进行通信的技术。这个技术允许一个Java对象在一台机器上执行方法,而这个方法的实现实际上位于另一台...
Java 远程方法调用(Java RMI,Remote Method Invocation)是Java平台提供的一种用于构建分布式应用程序的技术。它允许一个对象在某个Java虚拟机(JVM)上执行的方法调用另一个在不同JVM上的对象的方法,仿佛它们是...
Java Remote Method Invocation(Java RMI)是一种允许开发者创建分布式应用程序的技术。Java RMI 允许对象在另一个 Java 虚拟机(JVM)上调用远程 Java 对象的方法,可能在不同的主机上。Java RMI 使用对象序列化来...
Java 远程方法调用(Remote Method Invocation,RMI)是一种在分布式环境中调用对象方法的技术,它使得Java应用程序能够透明地调用运行在不同 JVM 上的远程对象的方法。RMI 包含了一系列的参数,这些参数对于优化...
RMI(Remote Method Invocation,远程方法调用)是Java平台中用于分布式计算的一种技术,它允许一个Java对象调用另一个在不同 JVM(Java虚拟机)上的对象的方法,从而实现跨网络的通信。Java RMI 提供了一种透明的...
Java Remote Method Invocation(Java RMI)是一种允许分布式应用程序在Java平台上运行的技术。它允许在不同的Java虚拟机(JVM)上运行的对象之间调用方法,从而实现分布式计算和信息-sharing。 Java RMI使用对象...
Java Remote Method Invocation (RMI) 是Java平台提供的一种用于创建分布式应用程序的技术,它允许对象在不同的JVM(Java虚拟机)之间通过网络进行方法调用。RMI的主要优点是其透明性,即开发者可以像调用本地方法...
本文探讨的是一种基于动态代理的Java远程调用框架,旨在解决传统远程调用技术如RMI(Remote Method Invocation)所面临的挑战。 RMI是Java平台上的基础远程调用技术,自JDK 1.1开始引入。它允许对象方法在不同的JVM...
Java RMI(Remote Method Invocation,远程方法调用)是Java平台提供的一种分布式计算技术,它允许在不同的Java虚拟机之间透明地调用对象的方法。在RMI架构中,客户端能够像调用本地对象一样调用远程服务器上的对象...
Java Platform, Standard Edition 的 Java Remote Method Invocation API Guide 介绍了 Java Remote Method Invocation(Java RMI)的概念和应用。Java RMI 是一种分布式应用程序开发技术,允许对象在不同的 Java ...
Java RMI(Remote Method Invocation,远程方法调用)是Java平台提供的一种用于分布式计算的技术,它允许一个Java对象调用另一个在不同JVM上的对象的方法。这个简单的例子将引导我们了解如何利用Java RMI实现远程...
Java远程方法调用(Remote Method Invocation,简称RMI)是Java平台中用于分布式计算的核心技术。它允许一个Java对象在一台机器上调用另一台机器上的对象的方法,仿佛这些方法是在本地对象上调用一样。本篇文章将对...
Java RMI(Remote Method Invocation,远程方法调用)是Java平台提供的一种用于在不同Java虚拟机之间进行远程通信的技术。通过RMI,开发者可以透明地调用运行在其他网络节点上的对象的方法,就像它们是在本地一样。...