我一直没有掌握java的类加载器,直到最近我看log4j2的源码时又好好研究了一下,才稍微懂点。在log4j2中有个功能是收集某个包下面的所有的类,以及写在某个文件中的类,这些都是需要classloader来完成的,于是顺着他的思路以及自己做实验我才慢慢稍微掌握了classLoader。
java的classLoader分为好几类,并且是有阶级关系的,一层一层的继承。最跟类是java自带的,这个我们看不到,他负责加载java运行时的一些核心class(比如JAVA_HOME/jre下面的类),这个加载器不需要我们操心,因为他不会给我带来麻烦和不会带来坏处,他是java的底层。还有一个也是不需要操心的——java的拓展类加载器,这个是刚才提到的classLoader的一个子类,也是用来加载一些核心类(我从网上搜,也是说加载JAVA_HOME/jre下面的类)。第三个是系统类加载器,这个继承自刚刚说的第二个classLoader,他负责加载classpath下的类,我们在系统变量里面配置的classpath就是起到这个作用。当我们在程序里面有一段代码时(不是在容器里面运行,而是手动的javac之后 java),我们就会发现他会使用一个叫做sun.misc.Launcher$AppClassLoader 的类加载器,他会加载当前类的原因就是因为classpath里面有个“.”,表示当前的目录下面进行查找,我猜测这个应该就是上面说的系统类加载器。
代码很简单,这里就不上了,记住不是在容器里面跑的,而是调用的 java命令。
但是在容器里面执行时就不一样了,比如我们可以在tomcat下有一个app(使用的springmvc),他的有个controller里面的方法如下:
@RequestMapping("a.do") @ResponseBody public void a() { System.out.println(A.class.getClassLoader()); }
当访问这个controller的时候就会打印如下的classloader:
WebappClassLoader
context: /spring
delegate: false
repositories:
/WEB-INF/classes/
----------> Parent Classloader:
org.apache.catalina.loader.StandardClassLoader@3b5b0734
很明显他是apache的一个classloader,也就是tomcat的,所以很明显是tomcat自己写的classloader,然后从/WEB-INF/classes下面加载class。也就是说我们可以自己写classloader来加载指定路径下面的class。在classloader的官方文档(jdk7)中,有这么一句话:Applications implement subclasses of ClassLoader in order to extend the manner in which the Java virtual machine dynamically loads classes:翻译过来是应用程序可以自己实现ClassLoader以创建自己的类加载器,可以拓展jvm加载类的方式。也就是说我们自己定义的classloader必须实现jdk的java.lang.Classloader类(我自己没有手动实验)
类加载器是基于父类委托的方式,即每一次加载一个类的时候会先委托给父亲进行加载,如果父亲加载到了就使用父亲找到的那个class,如果父亲没有加载到,才会自己加载。这样做的好处是使得jvm变得更加安全,如果没有父类委托机制的话我们可以写一个classloader,然后加载java.lang.String类,这样所有的String类就会都被改变了,导致jvm无法运行,而如果有了父类加载机制,这样的事情就不会发生,java的核心加载器也就是我们定义的加载器的父类已经加载了jdk的String类,我们即使手动的加载一个我们自己写的java.lang.String也无法成功。
相关推荐
类加载器是 Java 语言的一个创新,也是 Java 语言流行的重要原因之一。它使得 Java 类可以被动态加载到 Java 虚拟机中并执行。类加载器从 JDK 1.0 就出现了,最初是为了满足 Java Applet 的需要而开发出来的。Java ...
看完一个Java加载原理教程后,写了这个自己的类加载器,作个笔记,以便以且使用
自定义类加载器实现自定义加载。自定义类加载器实现自定义加载
DevLoader.zip tomcat 类加载器
Java类加载器可以直接从Maven存储库加载并运行类,能在运行时解决依赖关系
当JVM(Java虚拟机)启动时,会形成由三个类加载器组成的初始类加载器层次结构,理解类加载器:J2EE 环境下的 log4j.files
简单的自定义类加载器问候世界hello word,基于磁盘的ClassLoader
类装载器学习一、类加载器的基本概念 类装载器学习一、类加载器的基本概念 类装载器学习一、类加载器的基本概念
java 类加密 使用类加载器解密加载类 反射执行main
类加载器
ClassLoader 三种类加载方式 Boostrap Extenxsion 以及Application ClassLoad分别适用的场景
JDK(Java Development Kit) 是 Java 语言的软件开发工具包(SDK)。 SE(J2SE),standard edition,标准版,是我们通常用的一个版本,从JDK 5.0开始,改名为Java SE。
java应用程序类加载器(ClassLoader for java Application),类似exe4j, 方便启动java程序, 配置灵活,支持多平台选择性配置
(父子关系一般不会以继承的关系实现,而是以组合关系来复用父加载器的代码)工作过程如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把这个请
什么是类加载器和什么是双亲委派机制
ClassLoader的API使用和自定义
类加载器是Java最强大的特征之一。但是开发者常常忘记类加载组件。类加载器是在运行时负责寻找和加载类文件的类。Java允许使用不同的类加载器,甚至自定义的类加载器。类加载器从源文件(通常是.class 或 .jar文件)...
3-7Tomcat中自定义类加载器的使用与源码实现(1).mp4
java类加载器学习三、类加载器的委托模式