前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >深入理解Java类加载机制-自定义类加载器

深入理解Java类加载机制-自定义类加载器

作者头像
shysh95
发布2021-03-16 11:17:31
4550
发布2021-03-16 11:17:31
举报
文章被收录于专栏:shysh95

1. 打破双亲委派

Java类加载器的实现采用双亲委派原则,通过双亲委派原则,我们可以很好的保护Java程序在运行时的安全,越基础的类越会被上层的类加载器(例如启动类加载器)加载, 但是这种双亲委派在有些时候也会成为约束。比如当我的基础类需要调用用户自实现的类的将会发生问题,由于委派是向父类委派,因此用户自实现的类无法加载(没有类加载器可以加载), 因此调用会失败。此时我们就需要打破这种约束,让父类加载器可以触发子类记载器去加载特定的类。

其实上述情况在Java中已经存在,典型的例子便是JDNI服务,JDNI服务的代码由启动类加载器去加载(rt.jar),但在具体的实现时则需要调用各个厂商的具体实现,这些具体实现 (SPI,Service Provider Interface)则是保存在用户的类路径下。

为了解决这个问题,Java引入了一个不太优雅的设计:线程上下文类加载器,这个类加载器可以通过Thread.setContextClassLoader()来设置,如果创建线程时 没有设置,将会从父线程进行继承,如果全局都没有进行设置,那么这个类加载器默认则是应用程序类加载器。

2. 实现加载器

为了更好的巩固类加载器,我们特地自实现一个自己的类加载器,该类加载模拟的是ServiceLoader,ServiceLoader通常用在SPI机制里面,它打破了双亲委派机制, 使得父类加载器可以访问子类加载器加载的类。

实现大致分为三个模块:

  • classloader-core:类加载器的核心实现
  • wechat-classloader:模拟厂商提供的具体实现
  • client:模拟我们的客户端,使用厂商提供的具体实现

2.1 classloader-core

classloader-core包含了三个关键类:

  • Driver:接口,具体的实现由wechat-classloader实现
  • DriverManager:Driver管理类,client可使用它获取具体的Driver,并且执行相关方法
  • ServiceLoader:自定义的类加载器

classloader-core模块在运行时我会设置使用ExtClassLoader进行加载,将他当做Java提出来的规范。

2.1.1 ServiceLoader

ServiceLoader作为核心的核心,我单独介绍一下,ServiceLoader主要加载META-INF/sh-services/路径下的所有接口的具体实现类,如下图:

该文件的内容为该接口的具体实现类,由于我们只是做演示了解整个类加载的过程,因此ServiceLoader的实现相对简单,没有使用懒加载也没有使用缓存。

核心:

  • final Classservices属性:接口
  • final ClassLoader loader:具体的类加载器,使用Thread.getContextClassLoader(),这里得到的是默认的AppClassLoader

2.2 wechat-classloader

Driver的具体实现,例如JDBC的jar包

2.3 client

具体的应用程序,我们的应用程序会使用到classloader-core,wechat-classloader,触发对应的类加载器。

client的时序图如下:

运行程序

代码语言:javascript
复制
./gradlew build
# /Users/sh/workspace/ClassLoader/classloader-core/build/libs/这个目录替换成classloader-core的jar包所在的目录
java -Djava.ext.dirs=$JAVA_HOME/jre/lib/ext:/Users/sh/workspace/ClassLoader/classloader-core/build/libs/ -jar client/build/libs/client-1.0-SNAPSHOT.jar

结果如下:

本期自定义类加载器介绍到这,我们下期再见!!!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-02-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员修炼笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档