引用

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()会发现实际上不会起作用,这是由于要想实现同一个类的不同版本的共存,这些不同的版本必须由不同的类加载器进行加载,因此就不能把这些类的加载工作委托给类加载器来完成,因为它们只有一份。

最新文章

  1. springmvc上传文件,抄别人的
  2. C++序列化、反序列化
  3. 如何消除inline-block元素间间距问题(转)
  4. servlet/jsp详解
  5. SQL Server 数据库的安全管理(登录、角色、权限)
  6. 浅谈Oracle表之间各种连接
  7. BZOJ1114 : [POI2008]鲁滨逊逃生Rob
  8. Intellij IDEA @Override 标红
  9. ActionScript基本语法讲解
  10. Android java.lang.ClassCastException
  11. C#的tooltip自动消失之后就不再显示了解决办法
  12. js设置文本框只能输入数字
  13. android开发艺术探索读书笔记之-------view的事件分发机制
  14. Java编程之委托代理回调、内部类以及匿名内部类回调(闭包回调)
  15. 深入分析Java的String类的方法与特点
  16. PHP和Go中的闭包变量作用域
  17. VUE-011-通过 v-if 和 v-for 实现特定值的列表循环匹配,并显示满足匹配条件的值
  18. POJ 2378.Tree Cutting 树形dp 树的重心
  19. 错误记录:vue跟vue编译器版本不一致
  20. json 的类型

热门文章

  1. uploadify 上传文件插件
  2. Js 将图片的绝对路径转换为base64编码(2)
  3. kubeDNS workflow(service registration and discovery)
  4. Linux学习篇之OpenKM的安装(汉化)
  5. auth
  6. WEB 服务应用 Nginx之安装篇
  7. centos7 yum快速安装LNMP
  8. noi.ac NA531 【神树和物品】
  9. Github首次使用,上传代码
  10. 利用java8新特性,用简洁高效的代码来实现一些数据处理