/**

*  转载请注明作者longdick    http://longdick.iteye.com

*

*/

java应用环境中不同的class分别由不同的ClassLoader负责加载。 一个jvm中默认的classloader有Bootstrap ClassLoader、Extension ClassLoader、App ClassLoader,分别各司其职:

  • Bootstrap ClassLoader  负责加载java基础类,主要是 %JRE_HOME/lib/ 目录下的rt.jar、resources.jar、charsets.jar和class等
  • Extension ClassLoader    负责加载java扩展类,主要是 %JRE_HOME/lib/ext 目录下的jar和class
  • App ClassLoader          负责加载当前java应用的classpath中的所有类。

其中Bootstrap ClassLoader是JVM级别的,由C++撰写;Extension ClassLoader、App ClassLoader都是java类,都继承自URLClassLoader超类。 Bootstrap ClassLoader由JVM启动,然后初始化sun.misc.Launcher ,sun.misc.Launcher初始化Extension ClassLoader、App ClassLoader。

下图是ClassLoader的加载类流程图,以加载一个类的过程类示例说明整个ClassLoader的过程。

Bootstrap ClassLoader、Extension ClassLoader、App ClassLoader三者的关系如下:

Bootstrap ClassLoader是Extension ClassLoader的parent,Extension ClassLoader是App ClassLoader的parent。

但是这并不是继承关系,只是语义上的定义,基本上,每一个ClassLoader实现,都有一个Parent ClassLoader。

可以通过ClassLoader的getParent方法得到当前ClassLoader的parent。Bootstrap ClassLoader比较特殊,因为它不是java class所以Extension ClassLoader的getParent方法返回的是NULL。

了解了ClassLoader的原理和流程以后,我们可以试试自定义ClassLoader。

关于自定义ClassLoader:

由于一些特殊的需求,我们可能需要定制ClassLoader的加载行为,这时候就需要自定义ClassLoader了.

自定义ClassLoader需要继承ClassLoader抽象类,重写findClass方法,这个方法定义了ClassLoader查找class的方式。

主要可以扩展的方法有:

findClass          定义查找Class的方式

defineClass       将类文件字节码加载为jvm中的class

findResource    定义查找资源的方式

如果嫌麻烦的话,我们可以直接使用或继承已有的ClassLoader实现,比如

  • java.net.URLClassLoader
  • java.security.SecureClassLoader
  • java.rmi.server.RMIClassLoader
  • sun.applet.AppletClassLoader

Extension ClassLoader 和 App ClassLoader都是java.net.URLClassLoader的子类。

这个是URLClassLoader的构造方法:

public URLClassLoader(URL[] urls, ClassLoader parent)

public URLClassLoader(URL[] urls)

urls参数是需要加载的ClassPath url数组,可以指定parent ClassLoader,不指定的话默认以当前调用类的ClassLoader为parent。

代码示例:

  1. ClassLoader classLoader = new URLClassLoader(urls);
  2. Thread.currentThread().setContextClassLoader(classLoader);
  3. Class clazz=classLoader.loadClass("com.company.MyClass");//使用loadClass方法加载class,这个class是在urls参数指定的classpath下边。
  4. Method taskMethod = clazz.getMethod("doTask", String.class, String.class);//然后我们就可以用反射做些事情了
  5. taskMethod.invoke(clazz.newInstance(),"hello","world");
ClassLoader classLoader = new URLClassLoader(urls);
Thread.currentThread().setContextClassLoader(classLoader);
Class clazz=classLoader.loadClass("com.company.MyClass");//使用loadClass方法加载class,这个class是在urls参数指定的classpath下边。 Method taskMethod = clazz.getMethod("doTask", String.class, String.class);//然后我们就可以用反射做些事情了
taskMethod.invoke(clazz.newInstance(),"hello","world");

由于classloader 加载类用的是全盘负责委托机制。所谓全盘负责,即是当一个classloader加载一个Class的时候,这个Class所依赖的和引用的所有 Class也由这个classloader负责载入,除非是显式的使用另外一个classloader载入。

所以,当我们自定义的classloader加载成功了com.company.MyClass以后,MyClass里所有依赖的class都由这个classLoader来加载完成。

自定义ClassLoader在某些应用场景还是比较适用,特别是需要灵活地动态加载class的时候。

下面这篇文章列出了其中一种自定义ClassLoader的应用场景,有兴趣的同学可以参考下:

classloader加载过程的更多相关文章

  1. JVM ClassLoader加载过程

    虚拟机把描述类的数据从Class文件加载到内存,并对数据进行校验.转换解析和初始化,最终形成可以被虚拟机直接使用的Java类型,这就是Java虚拟机的类加载机制. 1)三个类加载器: bootstra ...

  2. java 反射,类的加载过程以及Classloader类加载器

    首先自定义一个类Person package reflection; public class Person { private String name; public int age; public ...

  3. 图解classloader加载class的流程及自定义ClassLoader

    图解classloader加载class的流程及自定义ClassLoader 博客分类: JVM JavaJVM虚拟机EXTSUN /** *  转载请注明作者longdick    http://l ...

  4. JVM——类的加载过程

    附一张图方便理解,一个类的执行过程 类的加载过程,简明的来说 类装饰器就是寻找类的字节码文件并构造出类在JVM内部表示的对象组件.在Java中,类装载器把一个类装入JVM中,要经过以下步骤: 装载:查 ...

  5. spring容器启动的加载过程(三)

    第十步: public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader { /** * Load bean def ...

  6. Spring IOC bean加载过程

    首先我们不要在学习Spring的开始产生畏难情绪.Spring没有臆想的那么高深,相反,它帮我们再项目开发中制定项目框架,简化项目开发.它的主要功能是将项目开发中繁琐的过程流程化,模式化,使用户仅在固 ...

  7. classloader加载的双亲委托模式

    要深入了解ClassLoader,首先就要知道ClassLoader是用来干什么的,顾名思义,它就是用来加载Class文件到JVM,以供程序使用 的.我们知道,java程序可以动态加载类定义,而这个动 ...

  8. (转)JVM类生命周期概述:加载时机与加载过程

    原文地址: http://blog.csdn.net/justloveyou_/article/details/72466105 JVM类加载机制主要包括两个问题:类加载的时机与步骤 和 类加载的方式 ...

  9. SSH 之 Spring的源码(一)——Bean加载过程

    看看Spring的源码,看看巨人的底层实现,拓展思路,为了更好的理解原理,看看源码,深入浅出吧.本文基于Spring 4.0.8版本. 首先Web项目使用Spring是通过在web.xml里面配置 o ...

随机推荐

  1. 多线程程序设计学习(3)immutable pattern模式

    Immutable pattern[坚不可摧模式] 一:immutable pattern的参与者--->immutable(不变的)参与者        1.1:immutable参与者是一个 ...

  2. IE下JS接受ActiveX控件方法

    1.常规写法 <SCRIPT type="text/javascript" FOR="activexID" EVENT="onXXXevent( ...

  3. Delphi 编译错误信息表

    ; not allowed before ELSE ElSE前不允许有“;” <clause> clause not allowed in OLE automation section 在 ...

  4. 自定义控件:抽屉SlidingDrawer——wrap_content非全屏

    android:allowSingleTap   指示抽屉是否可以打开/通过手柄上的一个水龙头关闭. android:animateOnClick  表示所述抽屉是否应该打开/与当用户点击手柄动画关闭 ...

  5. Selenium2Library系列 keywords 之 _SelectElementKeywords 之 page_should_not_contain_list(self, locator, message='', loglevel='INFO')

    def page_should_not_contain_list(self, locator, message='', loglevel='INFO'): """Veri ...

  6. 将webkit内核封装为duilib的浏览器控件

    转载请说明出处,谢谢~~ 原本的duilib是自带浏览器控件的,但是使用了IE内核,我在做仿酷狗音乐播放器时,在右侧乐库要用到浏览器控件,而我使用自带的IE控件却发现了不少缺点,这也是duilib一直 ...

  7. MATLAB常用数据类型的转换

    一直以来,在使用MATLAB进行运算的过程中,经常会用到对图像的各种处理,因此需要对图像进行数据转换,因此对经常用到的转换进行整理,方便查看. 1.uint8转化为double用来方便图像的运算: d ...

  8. sizeof和strlen小结

    sizeof和strlen小结 写在前面 之所以要总结一下sizeof和strlen的用法和区别,是因为这些知识可以帮助我们更加深入的理解各种数据结构在内存中的占用情况,也许表面上看好像没有多大用处, ...

  9. Windows安装pomelo过程

    安装总要出点状况的.操作系统是win7 64bit. 为了保证顺利,打开的是VS2012命令行提示.运行 npm install -g pomelo 经过一系列输出,最后安装提示完成了.但是输入 po ...

  10. 我是怎么发现并解决项目页面渲染效率问题的(IE调试工具探查器的使用)

    #我是怎么发现并解决项目页面渲染效率问题的(IE调试工具探查器的使用) ##背景 之前的项目中,有很多的登记页面,一般都有100-200甚至更加多的字段,而且还涉及到字典.日期及其他效果的显示,载入时 ...