http://blog.csdn.net/u013036274/article/details/54881002
http://blog.csdn.net/wugouzi/article/details/9404437
【Java类加载器】
JavaClassloader是Java运行时环境(Java Runtime Environment)的一部分,负责动态加载Java类到Java虚拟机的内存空间中。
类通常是按需加载,即第一次使用该类时才加载。由于有了类加载器,Java运行时系统不需要知道文件与文件系统。
JVM有三种类加载器:
1.启动类加载器(Bootstrap):是在jvm启动时创建的类加载器。它负责将(jre/lib)下面的核心类库或-Xbootclasspath选项指定的jar包加载到内存中。
2.扩展类加载器(Extension):是由Sun的ExtClassLoader(sun.misc.Launcher$ExtClassLoader)实现的。它负责将(jre/lib/ext)或者由系统变量-Djava.ext.dir指定位置中的类库加载到内存中。
3.系统类加载器(System):系统类加载器是由 Sun的AppClassLoader(sun.misc.Launcher$AppClassLoader)实现的。它负责将系统类路径java-classpath或-Djava.class.path变量所指的目录下的类库加载到内存中。
它们之间使用了双亲委派机制,如下图。简单说就是,当类加载器有加载需求的时候,先请示他的父类使用父类的搜索路径来加入,如果没有找到的话,才使用自己的搜索路径来来搜索类。
我们通过测试来看一下:
代码:
结果是:
测试结果表明:System类加载器的父加载器是Ext加载器,Ext类加载器的父加载器时得到了null,就是说Ext类加载器本身的父类加载器被设定为null,即用null来代表BootStrapLoader。
好,下面再来大致顺一下Java类加载机制的工作方式:
当执行 java ***.class 的时候, java.exe 会帮助我们找到 JRE ,找到位于 JRE/bin/server中的 jvm.dll ,JVM是Java虚拟机,有了虚拟机之后再加载动态库,激活 Java虚拟机。虚拟机器激活以后,会先做一些初始化的动作,比如说读取系统参数等。一旦初始化动作完成之后,就会产生第一个类加载器―― Bootstrap Loader(启动类加载器), Bootstrap Loader 是由 C++ 所撰写而成,这个 Bootstrap Loader所做的初始工作中,除了一些基本的初始化动作之外,最重要的就是加载 Launcher.java 之中的 ExtClassLoader(扩展类加载器),并设定其 Parent 为 null ,代表其父加载器为 BootstrapLoader 。然后 Bootstrap Loader再要求加载 Launcher.java 之中的System,并设定其 Parent 为之前产生的 ExtClassLoader实体。这两个加载器都是以静态类的形式存在的。
【Tomcat类加载器】
tomcat有自己的类加载机制,是在Java类加载机制上的一种扩展。如下图:
每个项目都有自己的类加载器。
除了Java本身的三种类加载机制外,其他的:
1.Common:加载TOMCAT_HOME/common/*,对Tomcat和所有的web项目都起作用。
2.Catalina:加载TOMCAT_HOME/server/*,对Tomcat起作用,对其他Web项目不起作用。
3.Shared:加载TOMCAT_HOME/shared/*,它对所有的Web项目都起作用,对Tomcat不起作用。
4.Web App相关加载器:加载每个web项目,只对当前web项目起作用。