Chinaunix首页 | 论坛 | 博客
  • 博客访问: 149524
  • 博文数量: 49
  • 博客积分: 2025
  • 博客等级: 大尉
  • 技术积分: 630
  • 用 户 组: 普通用户
  • 注册时间: 2007-05-11 11:27
文章分类

全部博文(49)

文章存档

2008年(49)

我的朋友

分类: Java

2008-08-19 13:35:53

类加载器是沙箱的第一道防线,毕竟代码都是由它装入jvm中的,其中也包括有危险的代码。它的安全作用有三点:
一 保护善意代码不受恶意代码的干扰
二 保护已验证的类库
三 代码放入有不同的行为限制的各个保护域中

类加载体系通过使用不同的类加载器把类放入不同的名字空间中从而保护善意代码不受恶意代码的干扰。

JVM为每个类加载器维护一个名字空间。例如,如果jvm在某个名字空间中加载了一个称为volcano的类,就不能再在这个名字空间中加载另一个也称为volcano的类,除非你再创建另一个名字空间。也就是说,如果jvm有三个名字空间,你就可以加载三个叫做volcano的类,一个名字空间一个。

在jvm中,同一个名字空间中的类是可以直接交互的,但在不同名字空间中的类就不行,除非提供另外的机制。这样,名字空间就起到了一个屏障的作用。

在图3-1中,显示了两个名字空间,各有一个类加载器,各加载了两个类型,两个名字空间都有一个叫做volcano的类型。左边颜色较深的类加载器加载了类型climber和volcano,右边颜色较浅的类加载器加载了类型bakingsoda和volcano。图中的箭头表示名字空间中的名字对在方法区(method area)中对应类型定义数据的引用。因为名字空间的屏障作用,当climber引用volcano时,是指的同一个名字空间中的volcano。尽管都在同一个jvm,它也无法知道另一个名字空间中的volcano,。如果想知道如何达到名字空间的分隔的,可以看第八章“链接模式”

类加载器体系可以通过使用不同的类加载器加载可信包(trusted packages)和不可信包(untrusted packages)从而保护可信包的安全。尽管你可以对同一包中的类型制定访问控制,但这种控制只有在被同一个加载器加载的前提下才起作用。

通常,一个用户定义的类加载器需要依赖其他类加载器来完成任务,至少需要一个在jvm启动时创建的类加载器,这个类加载器称为启动类加载器。在1.2版本以前,类加载器必须显示的调用其他类加载器,如调用其他用户定义的类加载器的loadClass方法,或者调用启动类加载器(bootstrap class loader)的静态函数findSystemClass()。
在1.2版本中,一个类加载器要求另一个类加载器加载某个类型的过程被规范化为代理模式(parent-delegation model 译者:就是Chain of Responsibility模式)

在某个类加载器试图以自己的方式加载一个类时,它首先缺省把这个工作交给自己的父对象。而这个父对象又会首先把这个任务交给自己的父对象处理,这样这个任务会一直传到启动类加载器,因为启动类加载器通常是代理链的最后一个类。如果父类加载器能够加载这个类型,就会返回此类型,否则由子类加载器处理。
在1.2版本以前的多数jvm的实现中,内建类加载器负责加载本地可用的类文件,通常包括java应用的类文件和所有这个应用需要的库,尽管加载所需类文件的方式根据应用不同而不同,但许多应用都以class path定义的路径来搜寻所需类文件。

在1.2版本中,加载本地可用类文件的任务被分解给了多个类加载器。以前称为原始类加载器(primordial class loader)的类加载器被改称为启动类加载器,用来表示它只用来加载核心java api的类文件,因为核心java api类文件是用来启动jvm的。

而负责加载其他类文件的任务都给了用户定义的类加载器(译者:这里指广义用户,包括虚拟机的实现者),这些类文件包括应用的类文件,用来进行安装和下载的标准扩展类文件,用来在class path中查找库的类文件等等。
因此当1.2的JVM开始运行时,它会创建至少一个用户定义的类加载器,所有的这些类加载器串成一个链,在链的头部是启动类加载器,在链的尾部是系统类加载器(system class loader)。在1.2之前,有时称内建类加载器为系统类加载

阅读(1079) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~