一、基本classloader体系
默认有3个classloader,分别是bootstrap、extension、app(system)
bootstrap是在JVM启动时加载的,会读取$JAVA_HOME/lib下的class
extension会读取$JAVA_HOME/lib/ext下的class
app,也称为system,加载应用程序所需的class,是由classpath变量指定的,如果在运行时不加-classpath参数,则默认会以当前目录为根路径
这3个classpath存在父子关系,遵循基本的委托模型,即当classloader被要求加载一个类时,它会首先委托parent classloader进行加载,如果没有找到,才会自己负责加载。这个设计主要是从安全性方面考虑
二、classloader相关的API
如果只是做应用层面的开发的话,可能都不会涉及到classloader的知识,只要知道上述的基本模型就可以了。但是如果要理解一些更复杂的东西,比如JNDI,或者开发应用服务器,或者实现一个插件体系的框架,那就需要对classloader的知识有更深入的了解
classloader存在的目的就是为了实现对class的加载。可以认为有3种classloader
第一种是整个应用总的classloader,可以通过以下API得到这个classloader实例
ClassLoader.getSystemClassLoader();
sun.misc.Launcher$AppClassLoader@addbf1
这个API我感觉作用并不大,因为用到这个API的场景并不多,如果是开发一个简单的应用,那么根本就不关注classloader是什么。如果是开发比较复杂的应用的话,得到系统总的classloader作用也不大,因为本来就是要替换它
第二种是当前的classloader。这里首先要明白一点。就是类A依赖类B的话,那么加载类B的classloader,也就是加载类A的classloader
比如说
ClassLoader appClassLoader = BindCase.class.getClassLoader();
等价于
ClassLoader appClassLoader = bindCase.getClass().getClassLoader();
都是得到加载BindCase这个类的classloader实例,如果bindCase实例又依赖了另一个类ClassB,那么默认情况下,ClassB也会由同一个classloader负责加载
当使用Class.forName()方法时,如果不显式传递一个classloader对象,则默认是使用当前的classloader
比如说
MyClassLoader mcl = new MyClassLoader();// 该ClassLoader可以读取外部类
Class.forName("xxx.xxx.xxx");
这段代码会抛ClassNotFoundException,虽然mcl可以加载外部类,但是它并不是“当前classloader”,当执行Class.forName()时,用的还是当前的classloader,所以外部类是加载不到的
第三种是当前线程的classloader。这里也有一个背景,每个线程都有一个ContextClassLoader,开启子线程之后,子线程的ContextClassLoader就是父线程的ContextClassLoader
以下两个API可以分别用来获取和设置ContextClassLoader
thread.getContextClassLoader();
thread.setContextClassLoader();
这2个API非常重要,因为可以起到传递classloader的作用,很多自定义的classloader体系,都用到了这2个API
三、一段实例测试代码
这段代码是模拟tomcat的加载过程
Bootstrap类在app classloader中加载,Catalina类在$CATALINA_HOME/lib/catalina.jar下,通过自定义classloader动态加载
public class Bootstrap {
public static void main(String[] args) throws MalformedURLException,
ClassNotFoundException {
String FQCN = "org.apache.catalina.startup.Catalina";// 要加载的目标类
try {
Class.forName(FQCN);// it's NOT OK
} catch (Exception e) {
e.printStackTrace();
}
try {
ClassLoader.getSystemClassLoader().loadClass(FQCN);// it's NOT OK
} catch (Exception e) {
e.printStackTrace();
}
try {
Bootstrap.class.getClassLoader().loadClass(FQCN);// it's NOT OK
} catch (Exception e) {
e.printStackTrace();
}
try {
Thread currentThread = Thread.currentThread();
currentThread.getContextClassLoader().loadClass(FQCN);// it's NOT OK
} catch (Exception e) {
e.printStackTrace();
}
ClassLoader myClassLoader = createClassLoader();
myClassLoader.loadClass(FQCN);// it's OK
System.out.println("over");
}
/**
* 实例化一个ClassLoader,加载了C盘根目录下的dummy_catalina.jar,其中包含Catalina类的定义
*/
private static ClassLoader createClassLoader() throws MalformedURLException {
String filePath = "c://dummy_catalina.jar";
File file = new File(filePath);
URL url = file.toURI().toURL();
URL[] urls = new URL[] { url };
ClassLoader myClassLoader = new URLClassLoader(urls);
return myClassLoader;
}
}
- 大小: 49 KB
分享到:
相关推荐
ClassLoader简介** ClassLoader是Java运行时系统中的一个重要组成部分,但常常被开发者所忽视。它的主要职责是在运行时查找并加载类文件。通过创建自定义的ClassLoader,开发者可以定制JVM的行为,实现对类加载...
#### 二、JDK简介 **JDK(Java Development Kit)**是Java语言的软件开发工具包(SDK)。JDK包含了Java运行环境(JRE)、Java编译器以及其他用于开发Java应用程序的工具。随着版本的发展,JDK经历了多个重要的变化。例如...
简介 “类装载器”(ClassLoader),顾名思义,就是用来动态装载class文件的。标准的Java SDK中有个ClassLoader类,借助此类可以装载需要的class文件,前提是ClassLoader类初始化必须制定class文件的路径。 import...
课程简介: 目前,Java是最为流行的编程语言之一,它的基础平台就是JVM。除了Java,如JRuby、Scala、Clojure等语言也运行在JVM平台。熟悉和掌握JVM平台有着重要的实用价值和意义。 在本课程中个,将详细介绍JVM的...
#### Java反序列化漏洞简介 Java序列化是指将对象的状态信息转换为可以存储或传输的形式的过程。相反,反序列化则是在适当的时候把这个流转换回原对象的过程。当应用程序接收来自不受信任源的数据并进行反序列化时...
Dalvik虚拟机简介** Dalvik是Google专门为Android设计的一种轻量级虚拟机,它基于寄存器架构,而不是传统的基于栈的虚拟机。这种设计使得Dalvik能够更好地适应移动设备的资源限制。在Android系统中,每个应用程序都...
#### 一、Java反射机制简介 Java反射机制是Java语言提供的一种强大特性,它使得程序可以在运行时动态地获取类的信息并直接操作对象的内部属性和方法。这种能力使得Java具备了一种动态语言的灵活性。 #### 二、Java...
- `newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)`:创建一个实现指定接口的代理实例。 通过上述类和方法,开发者可以实现诸如动态代理、序列化、元数据检查、运行时代码修改等...
#### 三、类加载器简介 在`newProxyInstance`方法中,`ClassLoader`是一个非常重要的参数。Java中主要有三种类型的类加载器: 1. **Bootstrap ClassLoader**:这是最基础的类加载器,使用C++编写,主要用于加载Java...
标题中提到的“Java虚拟机简介”即为Java平台的核心组件之一的Java Virtual Machine(JVM)的介绍。JVM是运行Java字节码的虚拟机,能够跨平台运行Java程序。它负责解释Java程序中的字节码,将它们转换为在特定硬件...
##### 装载过程简介 **装载**是指将类或接口的二进制形式(通常为`.class`文件)导入到JVM中,并创建相应的`Class`对象的过程。这个过程通常包括三个主要步骤:装载、链接和初始化。 - **装载**:查找并导入类或...
**JNI(Java Native Interface)简介** JNI,全称为Java Native Interface,是Java平台标准的一部分,它为Java应用程序提供了一个接口,使得Java代码可以调用本地(非Java)代码,如C、C++或汇编语言编写的功能。...
1. `properties`文件简介: `properties`文件是Java中的配置文件,它以键值对的形式存储数据,键和值之间用等号`=`或冒号`:`分隔。例如: ``` username=admin password=123456 ``` 2. `java.util.Properties`...
#### 一、JVM概述与HotSpot简介 Java虚拟机(JVM)是Java技术的核心组成部分之一,它为Java程序提供了运行时环境。本节将详细介绍JVM的基本概念及其核心技术——HotSpot。 **HotSpot VM** 是Oracle公司提供的一个高...
- **Extension ClassLoader**:解析Extension ClassLoader的工作原理及其与系统类加载器的关系。 - **System ClassLoader**:阐述System ClassLoader的功能,包括如何加载应用程序类。 - **全盘负责委托机制**:深入...
### Java虚拟机(JVM)简介 #### 一、Java虚拟机的概念 Java虚拟机(Java Virtual Machine,简称JVM)是Java技术的核心组成部分之一,在Java编程领域占据着至关重要的地位。简单来说,JVM可以被理解为一种通过软件...
简介 chapter_12 第12章 理解ClassLoader chapter_13 第13章 热修复原理 chapter_14 第14章 Hook技术 chapter_15 第15章 插件化技术 本书内容 本书共分为17章,各章内容如下: 第1章介绍Android系统...
#### HotSpot简介 HotSpot作为Oracle(原属SUN)的主要Java虚拟机实现,自2006年起开源,并成为OpenJDK项目的核心组成部分。它主要使用C++编写,支持多种操作系统和硬件架构。HotSpot的一个显著特点是采用了解析器...