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。

类加载器的双亲委派加载机制(重点):当一个类收到了类加载请求,他首先不会尝试自己去加载这个类,而是把这个请求委派给父类去完成,每一个层次类加载器都是如此,因此所有的加载请求都应该传送到启动类加载其中,只有当父类加载器反馈自己无法完成这个请求的时候(在它的加载路径下没有找到所需加载的Class),子类加载器才会尝试自己去加载。

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。

代码示例:

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加载class的流程及自定义ClassLoader的更多相关文章

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

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

  2. classloader加载过程

    /** *  转载请注明作者longdick    http://longdick.iteye.com * */ java应用环境中不同的class分别由不同的ClassLoader负责加载. 一个j ...

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

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

  4. Java ClassLoader加载机制理解 实际例子

    针对 Java ClassLoader加载机制理解, 做了个如何自定制简单的ClassLoader,并成功加载指定的类. 不废话,直接上代码. package com.chq.study.cl; im ...

  5. 从代码分析Android-Universal-Image-Loader的图片加载、显示流程

    从UNIVERSAL IMAGE LOADER. PART 3(四个DisplayImage重载方法详解)中,我们学习了Android-Universal-Image-Loader(以下简称UIL)中 ...

  6. HTML页面加载和解析流程详细介绍

    浏览器加载和渲染html的顺序 1. IE下载的顺序是从上到下,渲染的顺序也是从上到下,下载和渲染是同时进行的. 2. 在渲染到页面的某一部分时,其上面的所有部分都已经下载完成(并不是说所有相关联的元 ...

  7. html页面加载和解析流程

    HTML页面加载和解析流程 用户输入网址(假设是个html页面,并且是第一次访问),浏览器向服务器发出请求,服务器返回html文件: 浏览器开始载入html代码,发现<head>标签内有一 ...

  8. JVM ClassLoader加载过程

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

  9. 背水一战 Windows 10 (64) - 控件(WebView): 加载指定 HttpMethod 的请求, 自定义请求的 http header, app 与 js 的交互

    [源码下载] 背水一战 Windows 10 (64) - 控件(WebView): 加载指定 HttpMethod 的请求, 自定义请求的 http header, app 与 js 的交互 作者: ...

随机推荐

  1. 从输入url到页面展现的过程

    先看一幅图:(下面的所有图我都进行拉伸压缩了  如果看不到  可以右键复制图片地址 然后到浏览器粘贴查看  不然显示不全图片) mac没有画图软件  不好意思  xmind做的 1. 输入网址   当 ...

  2. 阶段3 1.Mybatis_05.使用Mybatis完成CRUD_7 Mybatis中参数的深入-使用实体类的包装对象作为查询条件

    pojo对象就是实体类 综合查询-实体类包装起来做查询 新建实体类QueryVo 提供一个User对象属性,并生成getter和setter 测试 修改dao接口中的返回类型为List<User ...

  3. Intellij IDEA 常见问题

    右击项目时,没有 Java Class,只能创建其他文件 IDEA 还没有将这个项目识别为 Maven 项目时,会出现这种情况.此时右键无法创建类. 解决办法: 手动为 IDEA 指定项目类型:如果编 ...

  4. 合理设置redis主从buffer 不错

    背景 某次抢购时,一个redis集群的某个分片,从实例响应时间陡增到几十秒,报警后运维将其中一个本应该下线的slave下掉,问题减轻但没有解决,又把另一个正常的slave下线掉,问题消失. maste ...

  5. CSS——插入形式 基本格式 常见css代码

    常见css代码 无下划线链接 字体颜色   +   左边距 背景颜色 字体.字体颜色.大小 文本对齐方式[取代了<center>]

  6. iptables添加开放端口

    查看状态 iptables -L -n 编辑/etc/sysconfig/iptables -A INPUT -p tcp -m tcp --dport 4000 -j ACCEPT 重启 servi ...

  7. Springboot2.x集成Redis集群模式

    Springboot2.x集成Redis集群模式 说明 Redis集群模式是Redis高可用方案的一种实现方式,通过集群模式可以实现Redis数据多处存储,以及自动的故障转移.如果想了解更多集群模式的 ...

  8. 【系统】win10锁屏后,护眼绿自动恢复解决

    针对自己电脑(其他人的不晓得),win10锁屏后,重新登录,护眼绿会自动恢复成白色,查询资料需要修改注册表两个地方: 1.计算机\HKEY_CURRENT_USER\Control Panel\Col ...

  9. 3-6如何在一个for语句中迭代多个可迭代对象

    1.并行迭代 迭代元组可以进行拆包迭代. >>> zip([1,2,3,4],('a','b','c','d')) [(1, 'a'), (2, 'b'), (3, 'c'), (4 ...

  10. POJ 3414 Pots (BFS/DFS)

    Pots Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7783   Accepted: 3261   Special Ju ...