类加载器种类及双亲委派机制

1 篇文章 0 订阅

类加载器

类加载器的作用就是将class文件加载到内存当中,并创建一个class对象。
怎么判断是否同一个类?
根据类的全限定名称(包名+类名)和类的加载器联合成一个唯一ID。不同的类加载器加载同一个类,相互之间不兼容的。
类加载器种类
bootstrap classloader(根类加载器)、extension classloader(扩展类加载器)、system classloader(系统加载器)。
bootstrap classloader(根类加载器):
根类加载器负责加载的是核心类库,根类加载器不是classloader的子类,是C++实现的;
主要加载的是%JAVA_HOME%/jre/lib/rt.jar包下的内容,比如:时间工具类、IO工具类、sql工具类等

extension classloader(扩展类加载器)
主要用来加载%JAVA_HOME%/jre/lib/ext包下的内容,我们自己写的工具类可以放在这个包下面。
jdk1.9后,扩展类加载器被平台类加载器所替换。
System classloader(系统类加载器) 又称 application classloader(应用类加载器)
加载应用程序中的类:我们自己编写的类、第三方类库中的类、环境变量classpath配置的jar包;
JVM主要的类加载机制
1)全盘托出:当一个类的加载器加载某个类,会把这个类所依赖和引用的其他类也加载出,除非这些类显示使用其它加载器;
2)父类委派(双亲委派):先让父类加载器加载class,当父类加载器不能加载时再有子加载器加载;
3)缓存机制:加载过的类都会存入缓存中;

自定义类加载器
除了根类加载器(C++实现的),所有加载器的父类都是classloader,所以我们要自定义加载器就需要继承classloader;
classloader中有两个重要方法:loadclass和findclass,我们只需要重写这两个方法,但是建议只需要重写
findclass方法,loadclass加载器会判断父加载器和根类加载器是否能加载,不能的话就会调用findclass方法加载;
自定义加载器应用场景举例:比如说java编译后的代码很容易被反编译,我们可以对编译后的代码进行加密,然后我们自定义类加载器先解密再加载;

双亲委派机制 文章详解
当类加载器收到类加载请求,自己不会先加载类,而是委托给自己的父类加载器去加载类,当父类加载器还有父类加载器,那么进一步向上委托,最终将加载请求交给启动类加载器(BootStrap ClassLoader)。
当父类加载器成功加载类则直接返回,若不能则向下交给子类加载器负责加载,这就是双亲委派机制。
优点:
1)防止类被重复加载;
2)保护核心类的安全性,防止核心API被随意篡改;
缺点:
在一些情况下双亲委派机制过于局限,所以我们需要打破双亲委派机制;
打破双亲委派机制的方法
1)自定义类加载器
自定义类加载器,我们需要继承ClassLoader类,主要重写其中的LoadClass方法和findClass方法;
如果我们不想打破双亲委派机制,只需要重写findClass方法;若想打破双亲委派机制,直接让自定义类加载器加载我们的类不经过父类加载器,需要重写loadClass方法,修改优先找父类加载器的判断;
2)使用线程上下文类加载器
通过spi机制或者自定义类加载器来打破双亲委派机制。
使用线程上下文类加载器更改类的加载器的种类,可以直接使用上下文加载器、也可以设置自定义的加载器为上下文加载器;
打破双亲委派机制的举例
1)JDBC打破双亲委派机制;
JDBC在进行数据库连接时,会先加载DriverManager类(该类是负责管理驱动程序、建立连接),因为这个类位于rt.jar包下面,所以会被启动类加载器加载;在这个类中会尝试加载所有Driver的实现类,但这些类基本上都是第三方提供的,所以不能被启动类加载器加载。于是就引入了ThreadContextClassLoader(线程上下文加载器,不使用线程上下文加载器默认使用的是应用程序类加载器),使用应用程序类加载器来破坏双亲委派机制加载第三方类。
2)Tomcat内部的加载器也是破坏双亲委派机制的
tomcat是web容器,一个Tmocat可能需要部署多个应用程序,多个应用程序可能会引用同一类库的不同版本,所以不同应用需要隔离加载类库,所以Tomcat为每个web容器都提供了一个WebAppClassLoader加载器,每一个WebAppClassLoader负责加载自己目录下的class文件,加载不到时再交给父类加载器CommonClassLoader加载,这正好违背了双亲委派机制;

  • 21
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值