文档章节

JAVA类加载机制以及如何自定义类加载器

xtuhcy
 xtuhcy
发布于 2016/06/15 18:35
字数 1024
阅读 199
收藏 0

##从双亲委派说起 输入图片说明

  • 启动(Bootstrap)类加载器:是用本地代码实现的类装入器,它负责将 <Java_Runtime_Home>/lib下面的类库加载到内存中(比如rt.jar)。由于引导类加载器涉及到虚拟机本地实现细节,开发者无法直接获取到启动类加载器的引用,所以不允许直接通过引用进行操作。
  • 标准扩展(Extension)类加载器:是由 Sun 的 ExtClassLoader(sun.misc.Launcher$ExtClassLoader)实现的。它负责将< Java_Runtime_Home >/lib/ext或者由系统变量 java.ext.dir指定位置中的类库加载到内存中。开发者可以直接使用标准扩展类加载器。
  • 系统(System)类加载器:是由 Sun 的 AppClassLoader(sun.misc.Launcher$AppClassLoader)实现的。它负责将系统类路径(CLASSPATH)中指定的类库加载到内存中。开发者可以直接使用系统类加载器。 除了以上列举的三种类加载器,还有一种比较特殊的类型 — 线程上下文类加载器。

双亲委派机制描述

  • 某个特定的类加载器在接到加载类的请求时,首先将加载任务委托给父类加载器,依次递归,如果父类加载器可以完成类加载任务,就成功返回;只有父类加载器无法完成此加载任务时,才自己去加载。

##Tomcat的类加载机制 本文主要以tomcat7为例说明类加载机制,大家也可以参考tomcat7的类加载机制的官方文档。Tomcat7总的ClassLoader结构如下图:

输入图片说明

各个类加载器加载类的范围:

  • Bootstrap:包括java虚机机的基本类,以及$JAVA_HOME/jre/lib/ext下的类。
  • System:包括CLASSPATH环境变量的类,主要是$CATALINA_HOME/bin/bootstrap.jar和$CATALINA_BASE/bin/tomcat-juli.jar两个jar包
  • Common:包括tomcat的基本类,主要是$CATALINA_BASE/lib下的所有jar包
  • WebappX:应用相关类,保证应用之间的类隔离。先加载/WEB-INF/classes,再加载/WEB-INF/lib/*.jar

加载顺序默认如下

  • Bootstrap classes of your JVM
  • /WEB-INF/classes of your web application
  • /WEB-INF/lib/*.jar of your web application
  • System class loader classes (described above)
  • Common class loader classes (described above)

如果设置了<Loader delegate="true"/>,加载顺序如下:

  • Bootstrap classes of your JVM
  • System class loader classes (described above)
  • Common class loader classes (described above)
  • /WEB-INF/classes of your web application
  • /WEB-INF/lib/*.jar of your web application

##setContextClassLoader的理解 JDK的解释是这样的:

Sets the context ClassLoader for this Thread. The context ClassLoader can be set when a thread is created, and allows the creator of the thread to provide the appropriate class loader, through , to code running in the thread when loading classes and resources.

**并不是给线程设置了ContextClassLoader,这个线程下加载的类就都使用该ContextClassLoader。**ContextClassLoader的用途是提供一个途径,使得线程运行时可以随时获得指定的ContextClassLoader进行类的加载,通过这个这种方式可以避开双亲委派模型,最典型的应用是JDBC、JNDI。

##自定义的ClassLoader 自定义的ClassLoader通过继承ClassLoader来实现,也可以使用URLClassLoader更简单。如果需要改写类的加载过程最好覆盖findClass()而不是loadClass(),loadClass()是为了保持jdk1.2之前的兼容。使用findClass()能保证不会违背双亲委派模式。

如何使用自定义的ClassLoader new出对象呢?前面说过的setContextClassLoader是不对的,必须用自定义的ClassLoader,通过反射实例化一个初始类,由该初始类加载的其他类就都会使用自定义的ClassLoader了。可以分析一下tomcat的代码:

Class<?> startupClass =
        catalinaLoader.loadClass
        ("org.apache.catalina.startup.Catalina");
    Object startupInstance = startupClass.newInstance();

通过反射机制调用startupInstance的方法,之后的类就会都有自定义的ClassLoader加载,当然有个前提就是不能违背双亲委派模型——自定义的ClassLoader加载的类在父ClassLoader加载的类中不存在。为什么要这么做?类加载的时候有一个规律,被加载类使用调用者所用的ClassLoader进行类的加载。可以通过Class.forName()的代码得到这个结论:

public static Class<?> forName(String className)
            throws ClassNotFoundException {
    Class<?> caller = Reflection.getCallerClass();
    return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
}

© 著作权归作者所有

xtuhcy

xtuhcy

粉丝 122
博文 18
码字总数 20733
作品 1
东城
后端工程师
私信 提问
加载中

评论(0)

Java Classloader机制解析

做Java开发,对于ClassLoader的机制是必须要熟悉的基础知识,本文针对Java ClassLoader的机制做一个简要的总结。因为不同的JVM的实现不同,本文所描述的内容均只限于Hotspot Jvm. 本文将会从...

aminqiao
2014/05/09
2.4W
2
浅谈java classloader

本文由作者张远道授权网易云社区发布。 类加载器三杰 jvm有三类classloader,分别是bootstrap classloader,extended classloader以及system classloader。 bootstrap classloader是系统在启动...

网易云
2018/12/14
0
0
深入浅出 ClassLoader

内容概述 “类加载”介绍 “类加载器”介绍 深入“类加载器” 深入“父亲委托机制” 一,“类加载”介绍 “加载”是类加载的时机的第一阶段。 类从被加载到虚拟机内存中开始,到卸载出内存为...

tomas家的小拨浪鼓
2019/08/04
0
0
图解Tomcat类加载机制(阿里面试题)

Tomcat的类加载机制是违反了双亲委托原则的,对于一些未加载的非基础类(Object,String等),各个web应用自己的类加载器(WebAppClassLoader)会优先加载,加载不到时再交给commonClassLoader走双...

群星纪元
2019/04/22
44
0
Java类加载器ClassLoader

JAVA类装载方式,有两种: 1.隐式装载, 程序在运行过程中当碰到通过new 等方式生成对象时,隐式调用类装载器加载对应的类到jvm中。 2.显式装载, 通过class.forname()等方法,显式加载需要的...

兴国First
2018/10/14
0
0

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周六乱弹 —— 现在看动弹的人都是什么状态

Osc乱弹歌单(2020)请戳(这里) 【今日歌曲】 @薛定谔的兄弟 :分享洛神有语创建的歌单「我喜欢的音乐」: 《夏日、教室与望着窗外的我》- Candy_Wind 手机党少年们想听歌,请使劲儿戳(这里...

小小编辑
45分钟前
68
1
wamp环境安装redis扩展

1.查看phpinfo信息根据配置信息下载对应的扩展 关键信息:VC14,TS,x86 2.下载php_redis和php_igbinary扩展 php_redis扩展下载地址: https://windows.php.net/downloads/pecl/snaps/redis...

点滴课程
59分钟前
36
0
开源商城开发笔记1-创建MyBatis示例

一、修改pom.xml,引入MyBatis,JUnit,Log4j <dependencies><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.4</version>......

土龙
今天
56
0
The Best Way To Learn English in 2020 (In my humble opinion.)

✅Here is the plan: THINGS YOU WILL NEED: - 1 hour per day (30 minutes will work as well). - a notebook and a pen to write down new vocabulary each day. - an English song. - an ......

FalconChen
昨天
73
0
nodejs 使用 pako 压缩数据

github https://github.com/nodeca/pako 应用场景 大对象传输一般使用json, 在worker或local storage中还必须使用字符串, pako可以对字符串或者 Uint8Array 数据进行压缩和解压, 牺牲一部分读...

阿豪boy
昨天
79
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部