- 浏览: 395346 次
- 性别:
- 来自: 杭州
博客专栏
-
Spring技术内幕读书笔...
浏览量:15658
文章分类
最新评论
-
albert0707:
非常感谢!
JAVA NIO 实例 -
greatwqs:
表露清晰, 言简意赅, 重新温习了一次
MySQL事务隔离级别详解 -
lgh1992314:
新版本都不需要了。ServiceLoader<Drive ...
DriverManager和Class.forName()的异同 -
zipmoon:
像以上的实验,就没有出现数据幻读的问题。 ---原因:My ...
MySQL事务隔离级别详解 -
jnjeC:
贴代码来了。大家还要根据代码做一定的修改。########## ...
MySQL事务隔离级别详解
对于 Java EE 开发来说, Java RMI 和 JNDOI 是两个非常重要的特性。 RMI 提供了远程调用的特性,而 JNDI 为应用程序提供了命名和目录服务,对于没有开发过大型项目的人来说,这些概念可能很陌生,那么为什么 Java EE 需要 JNDI 和 RMI 呢,这源于企业级开发的需要。分布式结构有以下几个企业级系统所必须的特性:
1. 性能:企业级系统需要强大的性能,单靠一台服务器通常无法满足性能需要,所以需要多台服务器协同工作。
2. 健壮性:冗余的服务器组成阵列,当某个服务器无法正常工作的时候,保证系统用户不受影响。
3. 可维护性:各个部分独立分开来,维护自己的运行状态,提高整个系统的灵活性和可维护性。
正是由于这些原因,企业级系统采用了分布式的结构,将系统分为各个不同的组件,各个组件之间靠消息或远程调用等机制来通信。在这种情况下就需要提供两类机制来保证组件之间能顺利协同工作。
a) 命名和目录机制:在分布式结构下,如何定位一个资源、一个对象就成为了非常重要的问题。打个比方,一个人若在一个团队里和伙伴协同工作,那么当他需要别人帮忙的时候,就需要知道如何去寻找他人,一个办法就是建立通讯录。同样的道理,如果对象 A 需要调用不再同一台服务器上的远程对象 B 提供的方法,那么对象 A 如何寻找对象 B 呢。这是也可以建立通讯录的机制, JNDI ( Java Nam Directory Interface : Java 命名和地址接口)就可以扮演通讯录的角色。利用 JNDI 的目录机制就相当于在通讯薄中翻查某个人的联系信息,当然,要使用通讯薄查找,首先要建立通讯薄,把具体的联系方式记录在通讯薄上,这就是 JNDI 提供的命名服务,也就是将资源绑定到目录上的简称。
b) 消息机制和远程调用机制:找到远程对象或者资源之后,可以发送消息来通信,也可以利用远程调用机制来直接调用远程对象的方法。前者属于一种松耦合的结构,双方仅仅通过消息作为媒介,不直接发生关系, JMS 实现了这种方式;而后者属于紧耦合的结构,也就是 RMI 方式, JavaRMI 是 Java Remote Method Interface 的简称。为什么需要 RMI ?设想一下,当对象 A 找到远程对象 B 之后,需要调用 B 的方法,但是调用 B 的方法,和调用本地的方法不同,由于 B 和 A 不在同一台服务器上(准确的说,不再同一台 JVM 中),就造成了很多的问题。
l 如何传递参数? Java 的参数传递是传引用而非传值的,所以 A 不能将指向本机内存中的一个引用当做参数传递给 B 。
l 当远程组件在不同平台、不同语言下运行的,又该如何与其进行通信。
一 用 Java RMI 实现远程调用
从很早之前开始,分布式环境就需要在不同主机之间进行进程通信和方法调用, RPC 就是为了这个目的而产生的,它允许一个程序访问另一台机器上的另一个程序的方法。而 RMI 在 RPC 的基础上更进一步, RPC 是远程访问程序方法,而 RMI 允许访问远程对象。所以和 RPC 相比,基于面向对象开发的 RMI 可以充分利用继承、封装和多态的面向对象开发的特点。
Java RMI 是 Java 的远程调用方式,利用它可以开发出分布式的远程对象,这些远程对象生存在不同的虚拟机上,并利用 RMI 协议进行通信。基本的 Java RMI 采用的是 JRMP ( Java Remote Method Protocol ),这个协议帮助 Java 远程对象进行通信,但是不支持对其他平台的支持,特别是对流行的 CORBA 的支持 (CORBA 支持 IIOP) ,所以在 Java RMI 的基础上,人们建立了 Java RMI - IIOP。
注意:远程是一个与实际位置无关的概念,一个远程对象可以和客户端在同一个机器上,也可以分别在网络上的两台机器上。
当然有了美好的愿望还不够,要实现 RMI 需要解决很多的问题。
1) 数据格式的兼容问题。在两个通信的组件之间数据格式会出现不一致,比如整数类型在A组件上是用2个字节表示的,而在B组件上是用4个字节表示的,这样当一个整数类型的参数从A组件传到B组件的时候,就会发生数据格式不一致的现象。这在 JAVA 之外的很多语言来说,是一个非常棘手的问题,但是 Java 的通用数据格式就避免了这种情况的发生。
2) 参数传递方式的选择,一般来说,程序设计有两种参数的传递方式:值传递( pass by value )和引用传递 (pass by reference) , 传值是将数据做一次拷贝,将拷贝得到的数据副本作为参数进行传递。用这种方式,被调用的方法中修改的只是数据的副本,而不是数据本身,所以原数据没有作修改。引用传递是将数据的引用传递,任何修改都将作用到数据本身。在远程调用的情况下,两种方式都可以传递参数,但都有一些问题。 对于值传递问题,由于是传递副本,所以远程对象的方法无法改变数据本身。另一个问题是若要传递对象参数,则需要将对象序列化,当对象空间很大的时候,序列化会带来很大的开销。 传递一个本地数据的引用到远程组件之后,远程组件根据此应用在其本地找到数据。所以还需要一次远程调用,往回访问引用数据本身。在 JavaRMI 中对这两种方式都支持。
3) 系统的不稳定性
在只有一个 JVM 的情况下,如果此 JVM 崩溃了,那么所有运行在其之上的程序全都一起失效,不会产生一部分对象仍然存在而另一部分消失的情况。但是在远程调用的环境中,有多个 JVM 在同时进行,如果其中一台 JVM 崩溃了,那么在其中的远程对象也消失,如果其他 JVM 中的对象不知道这些远程对象已经消失了,那么他们就会继续试图和这些“幽灵”对象进行通信,并发生异常。另外,由于远程对象之间通过网络进行通信,当网络发生故障的时候,对象应该得到通知。这些情况在 JavaRMI 中都得到了很好的支持。
要理解对象之间如何远程调用首先需要了解 Stubs( 存根 ) 和 Skeletons( 骨架 ) 的概念。假设有两个对象 A 和 B , B 是远程对象,提供方法供 A 调用,我们称 B 为服务器端,对象 A 是远程方法的调用方,我们称 A 为客户端。 JavaRMI 如何让 A 对象调用 B 的方法呢,实际上 JavaRMI 会在客户端模拟被调用的对象 B ,生成一个本地对象,这个本地对象就叫 Stub (存根),存根生存在客户端,但代表了远程对象,它接受 A 的方法调用,并将这些方法调用映射到远端实际 B 对象。对于对象 A 来说,由于有了存根的存在,远程调用形式看起来都和本地调用一致。
在 B 对象所在的服务器端,对应地存在 Skeleton( 骨架 ) , skeleton 是远程对象的代理,负责从网络接受调用的请求。并且将这些调用转移给实现的对象,所以可以认为,远程调用实际是通过 stub 和 skeleton 进行的。
客户端和服务器端都不直接和对方以及网络打交道,有了 stub 和 skeleton ,开发者可以从这些工作中解脱出来。
了解了 stubs 和 skeletons 之后,我们来看以下服务器端的远程对象。要使用远程对象首先要有一个远程接口。因为 RMI 调用的是远程接口。在面向对象设计中,一个基本的思想就是接口与实现相分离。接口定义了一个对象暴露给外界的信息。从一个用户来看,接口表示了这个用户能对这个对象进行的操作。而实现是程序内部的实际逻辑,是操作的具体过程,这一部分往往不需要暴露给外界。通过接口与实现的分离,开发者可以在不改变接口的情况下 ( 不改变用户的调用方式 ) ,改变程序方法的实现。
RMI 采用了同一思想,在 RMI 的远程调用中,客户端只能调用远程的接口。所以远程对象实现之前首先需要建立一个远程接口,此接口定义了这个远程对象对外提供的所有方法,同时此接口需要同时继承 java.rmi.Remote 接口,比如如下的代码:
import java.rmi.Remote; import java.rmi.RemoteException; public interface HelloInterface extends Remote { public void sayHello(String from)throws RemoteException; }
这里定义了一个接口 HelloInterface , 它继承了 Remote 接口,所以是一个远程接口。在接口 HelloInterface 中,自定义了 sayHello ()方法。这就是远程对象提供的方法。方法声明会抛出 RemoteException 异常,当网络不正常的情况出现的时候就会出现这个异常。开发者可以处理这个异常,决定当网络故障等情况出现时的程序行为。 (Java RMI 努力让网络变得透明,即远程调用和在本地调用形式上一致,但是同时开发者需要注意,网络问题是不可避免的。 )
定义了远程接口之后,就需要实现远程对象。远程对象实现了远程接口,提供具体功能的实现。要让一个对象成为一个远程对象,并且让远程宿主 ( 远程宿主:就是提供了对远程调用支持的容器,让它来控制远程对象。当远程接口被调用的时候,远程宿主自动调用远程对象的对应方法。 ) 可以调用它的方法,可以使用以下方式的任何一种:
继承 Javax.rmi.PortableRemoteObject 对象,这样当远程对象生成的时候,会自动调用 PortableRemoteObject 的构造函数,这个构造函数帮助对象可以被远程调用
手动将对象设置成远程对象。可能对象本身已经继承了某个基类,而无法继承 PortableRemoteObject, 这是需要手动将对象设置为远程对象:
javax.rmi.PortableRemoteObject.exportObject()
下面就是实现了 HelloInterface 接口的远程对象 HelloImpl
import java.rmi.RemoteException; import javax.rmi.PortableRemoteObject; public class HelloImpl extends PortableRemoteObject implements HelloInterface { protected HelloImpl() throws RemoteException { super(); } public void sayHello(String from)throws RemoteException { System.out.println("hello from"+from); System.out.flush(); } }
从上面的代码中,我们可以看到:
1) HelloImpl 继承 PortableRemoteObject 而称为远程对象
2) HelloImpl 实现 HelloInterface 远程接口
3) HelloImpl 的构造函数调用基类构造函数,并且此构造函数会抛出 RemoteException 异常。
4) HelloImpl 实现了 sayHello 方法。
在一个典型的远程对象的调用中,还需要有一个服务器端的应用来生成远程对象,并将其暴露给外界。同时还存在连接服务器端的客户端。接下来介绍调用远程对象时,如何传递参数。之前已经讲过,一般有两种传递参数的方式:值传递和引用传递。在 RMI-IIOP 中,对两种方式都支持。但实际上, RMI-IIOP 的参数传递是值传递的,引用传递是通过模拟的方式实现的。
Java RMI 的基本概念已经介绍完了,要使用远程对象,不仅要实现远程对象,换需要提供能够定位远程对象的机制,下面一节将要介绍 JNDI
发表评论
-
Java动态绑定机制的内幕(转载)
2011-05-19 22:45 2316在Java方法调用的过程中,JVM是如何知道调用的是哪个类的方 ... -
Static和Final的深度理解
2011-05-19 10:57 4134在Java中,static和final是使用频率非 ... -
自己动手写DataSource
2010-11-02 13:09 6341DataSource 对象所表示的物理数据源 ... -
DriverManager和Class.forName()的异同
2010-10-30 12:48 6593在学习JDBC的时候,通常有两种方式去注册数据库驱动程序(这里 ... -
Java的局部内部类以及final类型的参数和变量
2010-09-27 15:52 4746Thinking In Java里 ... -
JAVA NIO 实例
2010-09-18 03:32 46080最近一直在忙着JAVA NIO的知识,花了一下午 ... -
重载与覆盖区别
2010-09-16 23:40 3773重载与覆盖区别 有时候,类的同一种功能有多种实现方式, ... -
JAVA模拟线程池
2010-09-14 15:28 3125线程池就像数据库连接池一样,是一个对象池。所有的 ... -
HashCode和equals方法深度分析
2010-08-31 22:51 1535在往HashSet集合中放数据的时 ... -
[转]Java编码浅析
2010-08-29 16:09 1634Java与Unicode: Java的cl ... -
java final变量(转)
2010-08-26 14:47 2333final变量定义: 变量一经初始化就不能指向其它 ... -
JAVA中方法和变量在继承中的覆盖和隐藏
2010-08-24 13:07 2051关键字: java继承 方法覆盖 方法隐藏 ... -
java静态方法能否被重写
2010-08-24 11:52 13981JAVA静态方法 ... -
StringBuffer可变String不可变的真正原因
2010-08-23 19:19 2786String和StringBuffer 都是fi ... -
ANT笔记(二)
2010-06-09 09:01 2147四、 生成一个简单的 JA ... -
ANT笔记(一)
2010-06-09 08:59 1461一、 Ant ... -
Java的反射机制和动态代理
2010-06-09 08:29 2005运行时信息(RunT ... -
JNDI和Java RMI远程调用(二)
2010-06-07 21:22 5494利用 JNDI 定位资源 JNDI ... -
Java方法继承、方法重载、方法覆盖小总结
2010-03-17 14:59 1586Java方法继承、方法重载 ...
相关推荐
Java远程调用(Remote Method Invocation,RMI)是Java平台中一种重要的分布式计算技术,它允许在不同网络环境中的Java对象之间进行透明的交互。在本文中,我们将深入探讨三种不同的RMI实现方法:原始方式、Spring...
3. **RMI Registry**:RMI注册表是一个服务,用于存储远程对象的引用,它使用JNDI(Java Naming and Directory Interface)服务提供命名和目录功能。客户端通过注册表查找并获取远程对象的引用。 4. ** stubs 和 ...
### Java RMI 用于远程调用 进行分布式开发 #### 概述 Java RMI(Remote Method Invocation)是Java平台提供的一种实现分布式计算的技术,它允许开发者在不同JVM间进行方法调用,如同调用本地对象一样简单。通过...
在Java RMI中,一个JVM作为服务器,暴露远程接口,而其他JVM作为客户端,通过这些接口进行远程调用。 标题中的“rmi 远程调用 实现客户端之间会话”指的是利用RMI技术让多个客户端与同一服务端建立会话,进行交互。...
在实际应用中,RMI可以与其他Java技术如EJB、JMS(Java消息服务)和JNDI(Java命名和目录接口)结合使用,以构建复杂的分布式系统。然而,需要注意的是,虽然RMI提供了面向对象的远程调用,但它本身并不处理并发控制...
Java 分布式处理技术 RMI,JNDI Java 分布式处理技术是指在 Java 平台上实现分布式...RMI 和 JNDI 是 Java 分布式处理技术的核心组件,RMI 实现了对象之间的交互,而 JNDI 提供了一个统一的接口来访问不同的目录服务。
在"基于RMI的Java远程调用.pdf"文件中,可能会详细解释这些步骤,并提供示例代码来帮助读者理解和实践RMI技术。它可能会涵盖常见问题,如处理异常、优化性能、使用RMI-IIOP(RMI over IIOP,一种在CORBA基础设施上...
在Java编程领域,分布式系统和远程方法调用(Remote Method Invocation, RMI)是关键的高级概念,它们允许不同计算机间的程序协同工作,提高系统的可扩展性和灵活性。本篇文章将探讨如何使用Java来实现简单的分布式...
Java RMI(Remote Method Invocation,远程方法调用)是Java平台提供的一种用于在不同网络节点上的Java对象之间进行通信的技术。这个技术允许一个Java对象在一台机器上执行方法,而这个方法的实现实际上位于另一台...
- **生成存根和骨架**:使用Java RMI工具生成客户端和服务端的存根和骨架代码,以实现远程调用。 - **测试与部署**:编写测试应用程序验证远程对象的功能,最后部署应用程序并确保其正常运行。 #### 五、案例分析...
Java RMI(Remote Method Invocation,远程方法调用)是Java平台提供的一种分布式计算技术,它允许Java对象在不同的网络环境中进行交互,就像调用本地方法一样。RMI是构建分布式应用的重要工具,尤其适用于需要跨...
1. 定义远程接口:创建一个接口,继承自`java.rmi.Remote`,并在接口中声明将被远程调用的方法。方法声明中必须包含`throws RemoteException`,用于处理可能出现的远程通信异常。 2. 实现远程接口:创建一个类实现...
Java RMI(Remote Method Invocation,远程方法调用)是Java平台提供的一种分布式计算技术,它允许在不同的Java虚拟机之间进行方法调用,仿佛对象就在本地一样。RMI是Java在网络编程中的一个重要组成部分,尤其在...
首先,RMI的核心概念是远程方法调用,它允许一个Java对象调用位于另一台计算机上的对象的方法。这种机制依赖于Java的序列化机制,将远程对象的引用转化为可以在网络上传输的字节流,然后在目标机器上反序列化恢复...
总的来说,RMI是Java中实现分布式计算的关键技术,它通过存根、骨架和远程接口的机制,提供了透明的远程调用能力,简化了跨JVM的编程。开发者可以通过学习和理解RMI,构建出高效且易于维护的分布式系统。
1. 创建远程接口:首先定义一个继承自java.rmi.Remote的接口,声明所有要远程调用的方法。 ```java public interface MyRemoteInterface extends Remote { String doSomething(String input) throws ...
这种注入可以和RMI服务相结合,以实现攻击者定义的Java方法的远程调用。 文章中提到了JdbcRowSetImpl利用链和FastJson反序列化漏洞,这些是JNDI注入攻击利用的实例。JdbcRowSetImpl是Java的一个类,它允许通过JNDI...
骨架则在服务器端运行,它接收到客户端的远程调用,将这些调用转换为服务器上的本地调用,并将结果返回给客户端。存根和骨架由RMI编译工具自动生成,这个工具会分析服务器端的类,生成对应的存根和骨架代码。 RMI...