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 ...
随机推荐
- TypeScript 和 JavaScript 的区别
TypeScript 和 JavaScript 是目前项目开发中较为流行的两种脚本语言,我们已经熟知 TypeScript 是 JavaScript 的一个超集.JavaScript 和 TypeSc ...
- h5图片展示和ajax上传
<img src="" id="img"/> <script src="http://static.lamian.tv//pc/pu ...
- Delphi 数组与记录类型
- 第十篇.4、python并发编程之多线程
一 threading模块介绍 multiprocess模块的完全模仿了threading模块的接口,二者在使用层面,有很大的相似性,因而不再详细介绍 官网链接:https://docs.python ...
- centso 7 Keepalived 配置脚本
#!/bin/bash #This is keepalived bashshell. #MASTER/BACKUP yum install -y openssl openssl-devel keepa ...
- c++实现服务器和多个客户端的实时群聊通信
我们通过TCP/IP来实现多人聊天室,如果租一个服务器我们就可以实现全网的多人聊天室(不懂tcp/ip的点进来https://www.cnblogs.com/yskn/p/9335608.html)! ...
- java8学习之Collector源码分析与收集器核心
之前已经对流在使用上已经进行了大量应用了,也就是说对于它的应用是比较熟悉了,但是比较欠缺的是对于它底层的实现还不太了解,所以接下来准备大量通过阅读官方的javadoc反过来加深对咱们已经掌握这些知识更 ...
- 清北学堂提高组突破营考试T1
题目如下: (想要作弊的后几届神仙们我劝你们还是别黈了,这个题如果你们不会只能证明你们上错班了). 好,题目看完了,发现是一道大模拟(%你)题,于是我们按照题目说的做: #include<ios ...
- 使用Hbuilder打包app
使用Hbuilder来打包自己的H5项目 第一步 在Hbuilder上新建一个"移动APP"wolf(项目命名随意)(如果没用引用mui框架的东西,"选择模板" ...
- "main" java.io.IOException: Mkdirs failed to create /user/centos/hbase-staging (exists=false, cwd=file:/home/centos)
Exception in thread "main" java.io.IOException: Mkdirs failed to create /user/centos/hbase ...