java自定义classloader引发的思考
引用
classloader机制
- 如下图所示,java的classloader是双亲委派机制。会首先从父classloader加载指定的class,如果加载不到才会从子classloader中加载。
- 主要这里的图片主要用于体现classloader的父子关系,实际上实现时并不一定存在继承关系。比如
AppClassLoader
的父classLoader是ExtClassLoader
,但是实际实现时两者都是继承自URLClassLoader
的。
自定义classloader
Animal类&包结构
- 包结构如图:
测试入口
- 输出结果如图所示:
思考1
- 我们定义的classloader真的被运行了吗?
- 实际上如果打一些日志或者是debug进去看下,会发现我们重写的方法并没有被执行,这是java classloader的委派机制搞的鬼,我们可以发现定制的
TinglangClassLoader
的父classloader为URLClassLoader
,在URLClassLoader
中就已经找到了Animal
类了。 - 所以这里可以重写
loadClass
方法来保证我们的classLoader被执行。
思考2
- 我们将代码做一些变种,如下图所示:
- 执行结果直接抛异常了
- 这是由于
Animal
类来源于两个不同的类加载器。如果只是需要执行Animal
中的say
方法的话,直接反射调用即可,如下图所示:
思考3
- 我们再将代码做一下变化,如下图所示,
Animal
作为一个普通内部类来实现,如下图所示: - 可以看到代码已经提示无法实例化内部类了,这个是由于要实例化非静态的内部类对象,必须要先实例化外部类的对象,可以采用下面的方法来解决:
- ps:这里内部类有
public
修饰符~
思考4
- tomcat也是定义了自己的classloader,那么为啥不用jvm提供的classloader呢?
- 结合相关的资料主要是三个方面的目的:
- webapp隔离:由于各个webapp中的class和lib文件需要相互隔离,不能出现一个应用中加载的类库会影响到另一个应用的情况。
- 安全性:与jvm相同,tomcat也期望使用单独的classloader去装载tomcat自身的类库,以免其他恶意或者无意的破坏。
- 热部署:tomcat修改文件可以不用重启自动装载类库,这个点后面我们会单独抽取示例。
思考5
- 既然ExtClassLoader是读取特定目录下的class文件,那么如果我将自定义的class文件移到
$JAVA_HOME/jre/lib/ext/
目录下是不是就能够达到指定classloader加载类的目标呢? - 这个点是可以的,但是必须要求是jar。
思考6
- 类加载器常见的用途有类的隔离和热替换,类的隔离非常好理解,那么热替换呢?
- 仍然以我们之前的代码为例,如下图所示:
- 在程序运行过程中更新并编译
Animal
类中say方法 - 可以看到运行结果如图所示:
- ps:注意第一张图中的红色框框部分,如果修改为
Thread.currentThread().getContextClassLoader()
会发现实际上不会起作用,这是由于要想实现同一个类的不同版本的共存,这些不同的版本必须由不同的类加载器进行加载,因此就不能把这些类的加载工作委托给类加载器来完成,因为它们只有一份。
java自定义classloader引发的思考的更多相关文章
- 一次偶然的Java内存溢出引发的思考
据说一次SQL查询返回太多数据,会引起服务器内存溢出. 不过,我现在碰到的情况是,调用一个Postgresql 存储过程,很复杂,那么在其中有很多raise notice这样的调试语句,如果碰巧有个死 ...
- Java Se:自定义ClassLoader
JVM是如何知道java.lang包中的类的?JVM又是如何知道我们应用中的类的?我们的应用中明明是有某个类, 但是JVM却抛出ClassNotFoundException,这是为什么?XxxImpl ...
- JAVA 利用JNI加密class文件/自定义ClassLoader 类
利用 JNI 对bytecode 加密.不影响java程序员的正常开发.09年的时候写的,现在拿出来晒晒————————————————————————————混淆才是王道,如果混淆再加密就更酷了.. ...
- 一个ScheduledExecutorService启动的Java线程无故挂掉引发的思考
2018年12月12日18:44:53 一个ScheduledExecutorService启动的Java线程无故挂掉引发的思考 案件现场 不久前,在开发改造公司一个端到端监控日志系统的时候,出现了一 ...
- Java高级进阶:自定义ClassLoader
假如我们的类不在classpath下,而我们又想读取一个自定义的目录下的class,如果做呢? 读取自定义目录的类 示例读取c:/test/com/test.jdk/Key.class这个类. pac ...
- 自定义classLoader思考
jvm对于类实例的区分 基于完全限定名+classLoader 不同的classLoader可以加载同一class,生成不同实例, 但是这两个class实例生成的对象不能强转 spring boot ...
- Spring之LoadTimeWeaver——一个需求引发的思考---转
原文地址:http://www.myexception.cn/software-architecture-design/602651.html Spring之LoadTimeWeaver——一个需求引 ...
- java lang(ClassLoader)
一.什么是ClassLoader? 大家都知道,当我们写好一个Java程序之后,不是管是CS还是BS应用,都是由若干个.class文件组织而成的一个完整的Java应用程序,当程序在运行时,即会调用该程 ...
- 使用自定义 classloader 的正确姿势
详细的原理就不多说了,网上一大把, 但是, 看了很多很多, 即使看了jdk 源码, 说了罗里吧嗦, 还是不很明白: 到底如何正确自定义ClassLoader, 需要注意什么 ExtClassLoade ...
随机推荐
- MySQL索引详解(优缺点,何时需要/不需要创建索引,索引及sql语句的优化)
一.什么是索引? 索引是对数据库表中的一列或多列值进行排序的一种结构,使用索引可以快速访问数据库表中的特定信息. 二.索引的作用? 索引相当于图书上的目录,可以根据目录上的页码快速找到所需的内容,提 ...
- Caffe常用算子GPU和CPU对比
通过整理LeNet.AlexNet.VGG16.googLeNet.ResNet.MLP统计出的常用算子(不包括ReLU),表格是对比. Prelu Cpu版 Gpu版 for (int i = 0; ...
- Clang教程之实现源源变化
clang教程之实现源源变化 声明:本教程来自于Eli Bendersky's website 原文地址:http://eli.thegreenplace.net/2014/05/01/modern- ...
- js 格式化 json 字符串
1.JSON.stringify的三个参数 var json = {"@odata.context":"$metadata#AddTableOne_466281s&quo ...
- 使用Pechkin与CPechkin生成PDF
1. Pechkin 从NuGet程序管理器中获得Pechkin,代码示例如下: GlobalConfig config = new GlobalConfig(); ...
- VScode VUE+PYTHON习惯用的编辑器
本人从事运维开发工作,经常要开发一些web系统工具,这就需要用到前后端开发.vscode是我用得最舒服的一种编辑器,前端后端都习惯在上面写,这里记录一些配置. 一,插件安装 目前我最主要用的是: ...
- @EqualsAndHashCode
1.@Data注解包含了这些注解 * @see Getter * @see Setter * @see RequiredArgsConstructor * @see ToString * @see E ...
- BZOJ1257 [CQOI2007]余数之和[规律]
被zcr和yy轮流嘲讽了一番,感觉自己智商日渐下降...\TヘTツ 先拆mod变成整数除法,然后就是$nk- \Sigma_{i=1}^{n} i * \lfloor \frac{k}{i} \rfl ...
- 【leetcode】1255. Maximum Score Words Formed by Letters
题目如下: Given a list of words, list of single letters (might be repeating) and score of every charact ...
- user-select 用户禁止选中
我们在页面输入的文本按理来说应该都是可以选中的,但是如何才能让显示出来的文本或是图片不被选中呢,这时候就需要用到 user-select 属性. user-select user-select (CS ...