达内LOGO和北京达内网址达内科技培训项目:Java培训 3G培训 Android培训 软件测试培训北京达内服务电话
java培训
Java的类加载器简述
类加载器是java设计中一项创新,独立于JVM之外,类如何加载可以由JVM外部实现。如早期的Applets,曾经大红的OSGI等。

类加载器就是加载类的。一个jvm中可以存在若干个类加载器。相同的字节码因为类加载器不同,产生的实例肯定不同,即用instanceof 或者equal,isInstance()等方法对较相同字节码不同类加载器对象时返回均为false。

开发者可以继承java.lang.ClassLoader重写findClass(String clazz)或者loadClass(String clazz)实现自定义的ClassLoader。

*双亲委派模型

从开发者角度,类加载器有Bootstrap ClassLoader,Extension ClassLoader,System ClassLoader,self-defined ClassLoader.

其中BootstrapClassLoader用来加载$JAVA_HOME/lib下或-Xbootclasspath指定的核心库,其中包括java.lang下所有类。

ExtensionClassLoader加载$JAVA_HOME/lib/ext或者java.ext.dirs环境变量下类库。

SystemClassLoader为开发者程序默认加载器,用于加载ClassPaht下类库。

自jdk1.2以后,JVM加载类字节码时,采用双亲委派模型,即除了Bootstrap ClassLoader之外其他类加载器均有自己的父类加载器。一个类加载器加载一个字节码class时,首先把请求委派给父类加载器,每个加载器都这么干,如果没找到,则继续委派给Bootstrap类加载器。还没找到,才去自己找。通过该设计,其实维护了一种加载时的优先级关系。java.lang下类始终由等级最高的BootstrapClassLoader加载,即jvm中何时也只会出现一个java.lang.Object类。即使开发者使用自定义ClassLoader使用defineClass强行加载时也会通不过安全检查。

**双亲委派模型之外的特例

1 Thread Context ClassLoader:

主要用来解决Bootstrap ClassLoader在一些特定情况下如何加载SPI(Service Provider Interface)代码,如JNDI、JDBC、JCE等。SPI代码特殊性在于,SPI接口在java核心库提供,需要由bootstrap ClassLoader加载,而SPI实现则为第三方提供,按照上面的模型,启动类加载器无法识别第三方代码库。

线程上下文类加载器默认继承父线程的类加载器,不设置的话默认是system classLoader。所以SPI情况下都可通过线程上下文加载器加载字节码。

2 Class.forName方法

public static Class<?> forName(String className) throws ClassNotFoundException;

看源码可以知道,该方法使用调用者的ClassLoader加载类,并初始化类。

而另外重载方法

public static Class<?> forName(String name, boolean initialize,ClassLoader loader) throws ClassNotFoundException;

则可以定义是否初始化类,用什么ClassLoader加载类。

3 OSGI

Java的动态模块系统。它为开发人员提供了面向服务和基于组件的运行环境,并提供标准的方式用来管理软件的生命周期。典型产品就是Eclipse。

OSGI核心思想就是bundle。每个bundle由独立的ClassLoader加载,以java开头的包均由父类加载器加载,其他包则可以通过org.osgi.framework.bootdelegation参数定义由父类加载器加载。每个bundle可以定义需要import其他bundle的包或类,也可以定义需要export的包和类。这样bundle之间也可以建立类库的依赖关系。

OSGI通过bundle实现了组件或模块的热部署,需要更换bundle时,直接将bundle及其classloader换掉即可。通过OSGI提供的Service Ranking 思想,排名最高的服务被优先使用。而service rank值可以在注册bundle服务时指定。
更多相关信息知识,请关注:www.vip-tarena.com