高手支招 Java经验分享(六)

开发 后端
本篇文章是作者Ant_Yan在CSDN论坛上发布的自己对Java学习的一些经验分享。这是他经验分享的第六部分。

  本篇是我学习Java经验分享的第六篇,我打算在这里谈谈Java中的RMI机制和JVM沙箱安全框架。

  1. Java中的RMI机制

  RMI的全称是远程方法调用,相信不少朋友都听说过,基本的思路可以用一个经典比方来解释:A计算机想要计算一个两个数的加法,但A自己做不了,于是叫另外一台计算机B帮忙,B有计算加法的功能,A调用它就像调用这个功能是自己的一样方便。这个就叫做远程方法调用了。

  远程方法调用是EJB实现的支柱,建立分布式应用的核心思想。这个很好理解,再拿上面的计算加法例子,A只知道去call计算机B的方法,自己并没有B的那些功能,所以A计算机端就无法看到B执行这段功能的过程和代码,因为看都看不到,所以既没有机会窃取也没有机会去改动方法代码。EJB正式基于这样的思想来完成它的任务的。当简单的加法变成复杂的数据库操作和电子商务交易应用的时候,这样的安全性和分布式应用的便利性就表现出来优势了。

  好了,回到细节上,要如何实现远程方法调用呢?我希望大家学习任何技术的时候可以试着依赖自己的下意识判断,只要你的想法是合理健壮的,那么很可能实际上它就是这么做的,毕竟真理都蕴藏在平凡的生活细节中。这样只要带着一些薄弱的Java基础来思考RMI,其实也可以想出个大概来。

  a) 需要有一个服务器角色,它拥有真正的功能代码方法。例如B,它提供加法服务

  b) 如果想远程使用B的功能,需要知道B的IP地址

  c) 如果想远程使用B的功能,还需要知道B中那个特定服务的名字

  我们很自然可以想到这些,虽然不完善,但已经很接近正确的做法了。实际上RMI要得以实现还得意于Java一个很重要的特性,就是Java反射机制。我们需要知道服务的名字,但又必须隐藏实现的代码,如何去做呢?答案就是:接口!

  举个例子:

  1. public interface Person(){  
  2.   public void sayHello();  
  3.   }  
  4.   Public class PersonImplA implements Person{  
  5.   public PersonImplA(){}  
  6.   public void sayHello(){ System.out.println(“Hello!”);}  
  7.   }  
  8.   Public class PersonImplB implements Person{  
  9.   public PersonImplB(){}  
  10.   public void sayHello(){ System.out.println(“Nice to meet you!”);}  
  11.   }  
  12.   客户端:Person p = Naming.lookup(“PersonService”);  
  13.   p.sayHello(); 

  就这几段代码就包含了几乎所有的实现技术,大家相信么?客户端请求一个say hello服务,服务器运行时接到这个请求,利用Java反射机制的Class.newInstance()返回一个对象,但客户端不知道服务器返回的是ImplA还是ImplB,它接受用的参数签名是Person,它知道实现了Person接口的对象一定有sayHello()方法,这就意味着客户端并不知道服务器真正如何去实现的,但它通过了解Person接口明确了它要用的服务方法名字叫做sayHello()。

  如此类推,服务器只需要暴露自己的接口出来供客户端,所有客户端就可以自己选择需要的服务。这就像餐馆只要拿出自己的菜单出来让客户选择,就可以在后台厨房一道道的按需做出来,它怎么做的通常是不让客户知道的!(祖传菜谱吧,^_^)

  最后一点是我调用lookup,查找一个叫PersonService名字的对象,服务器只要看到这个名字,在自己的目录(相当于电话簿)中找到对应的对象名字提供服务就可以了,这个目录就叫做JNDI (Java命名与目录接口),相信大家也听过的。

  有兴趣的朋友不妨自己做个RMI的应用,很多前辈的博客中有简单的例子。提示一下利用Jdk的bin目录中rmi.exe和rmiregistry.exe两个命令就可以自己建起一个服务器,提供远程服务。因为例子很容易找,我就不自己举例子了!

  2. JVM沙箱&框架

  RMI罗唆得太多了,实在是尽力想把它说清楚,希望对大家有帮助。最后的最后,给大家简单讲一下JVM框架,我们叫做Java沙箱。Java沙箱的基本组件如下:

  a) 类装载器结构

  b) class文件检验器

  c) 内置于Java虚拟机的安全特性

  d) 安全管理器及Java API

  其中类装载器在3个方面对Java沙箱起作用:

  a. 它防止恶意代码去干涉善意的代码

  b. 它守护了被信任的类库边界

  c. 它将代码归入保护域,确定了代码可以进行哪些操作

  虚拟机为不同的类加载器载入的类提供不同的命名空间,命名空间由一系列唯一的名称组成,每一个被装载的类将有一个名字,这个命名空间是由Java虚拟机为每一个类装载器维护的,它们互相之间甚至不可见。

  我们常说的包(package)是在Java虚拟机第2版的规范第一次出现,正确定义是由同一个类装载器装载的、属于同一个包、多个类型的集合。类装载器采用的机制是双亲委派模式。具体的加载器框架我在Java杂谈(一)中已经解释过了,当时说最外层的加载器是AppClassLoader,其实算上网络层的话AppClassLoader也可以作为parent,还有更外层的加载器URLClassLoader。为了防止恶意攻击由URL加载进来的类文件我们当然需要分不同的访问命名空间,并且制定最安全的加载次序,简单来说就是两点:

  a. 从最内层JVM自带类加载器开始加载,外层恶意同名类得不到先加载而无法使用

  b. 由于严格通过包来区分了访问域,外层恶意的类通过内置代码也无法获得权限访问到内层类,破坏代码就自然无法生效。

  附:关于Java的平台无关性,有一个例子可以很明显的说明这个特性:

  一般来说,C或C++中的int占位宽度是根据目标平台的字长来决定的,这就意味着针对不同的平台编译同一个C++程序在运行时会有不同的行为。然而对于Java中的int都是32位的二进制补码标识的有符号整数,而float都是遵守IEEE 754浮点标准的32位浮点数。

  笔者只是抛砖引玉的提供给大家一个初步认识JVM的印象。有机会了解一下JVM的内部结构对今后做Java开发还是很有好处的。

【编辑推荐】

  1. 新手入门:学习Java的一点经验心得
  2. 61条Java面向对象设计的经验原则
  3. 经验分享:我的JavaEE学习道路
  4. Java对象类型转换的四个经验
  5. 高手支招 Java经验分享(一)
责任编辑:韩亚珊 来源: CSDN
相关推荐

2011-03-31 13:52:22

Java

2011-03-31 16:26:28

Java

2011-03-31 13:32:13

Java

2011-03-31 16:44:43

Java

2011-03-31 16:49:40

Java

2011-03-31 15:36:02

Java

2011-03-31 13:56:24

Java

2011-03-31 14:07:27

Java

2011-04-07 13:18:00

管理软件项目项目

2009-10-29 16:57:05

Oracle传输表空间

2018-06-19 08:12:55

2010-07-21 14:05:31

2014-05-28 10:55:11

Windows XP安全补丁

2010-10-19 14:57:25

谷歌云计算

2010-08-18 14:19:01

无线路由器

2009-09-28 10:52:00

CCNA考试经验CCNA

2009-02-23 11:22:29

系统架构师软件开发经验

2009-12-22 16:03:03

WCF异常

2009-12-18 17:01:37

Ruby基础代码

2009-12-22 19:26:51

WCF绑定
点赞
收藏

51CTO技术栈公众号