JVM笔记 – 虚拟机执行子系统(类加载及执行子系统的案例与实战)
本文由发表于3年前 | 未分类 | 暂无评论 |  被围观 1,605 views+
1、概述2、案例分析2.1、Tomcat:正统的类加载器架构Tomcat热部署原理2.2、OSGi:灵活的类加载器架构2.3、字节码生成技术与动态代理的实现2.4、Retrotranslator:跨越JDK版本3、实战:自己动手实现远程执行功能3.1、目标3.2、思路3.3、实现3.4、验证4、本章小结
《深入理解Java虚拟机:JVM高级特性与最佳实践(第2版)》笔记
1、概述

能通过程序进行操作的,主要是字节码生成与类加载器这两部分的功能。

2、案例分析
2.1、Tomcat:正统的类加载器架构

主流的 Java   Web 服务器,如 Tomcat、 Jetty、 WebLogic、 WebSphere 或其他笔者没有列举的服务器,都实现了自己定义的类加载器(一般都不止一个)。因为一个功能健全的 Web 服务器,要解决如下几个问题:

  • 部署在同一个服务器上的两个 Web 应用程序所使用的 Java 类库可以实现相互隔离。
  • 部署在同一个服务器上的两个 Web 应用程序所使用的 Java 类库可以互相共享。
  • 服务器需要尽可能地保证自身的安全不受部署的 Web 应用程序影响。
  • 支持 JSP 应用的 Web 服务器,大多数都需要支持 HotSwap 功能。

在部署 Web 应用时,单独的一个 ClassPath 就无法满足需求了,所以各种 Web 服务器都“不约而同”地提供了好几个 ClassPath 路径供用户存放第三方类库。

在 Tomcat 目录结构中,有 3 组目录("`/common/*`"、"`/server/*`" 和"`/shared/*`") 可以存放 Java 类库,另外还可以加上 Web 应用程序自身的目录"/ WEB- INF/*", 一共 4 组。

`CommonClassLoader`、 `CatalinaClassLoader`、 `SharedClassLoader` 和 `WebappClassLoader` 则是 Tomcat 自己定义的类加载器,

Tomcat热部署原理

JasperLoader 的加载范围仅仅是这个 JSP 文件所编译出来的那一个 Class, 它出现的目的就是为了被丢弃:当服务器检测到 JSP 文件被修改时,会替换掉目前的 JasperLoader 的实例,并通过再建立一个新的 Jsp 类加载器来实现 JSP 文件的 HotSwap 功能。

对于 Tomcat 的 6. x 版本,只有指定了 tomcat/conf/ catalina. properties 配置文件的 server.loader 和 share.loader 项后才会真正建立 CatalinaClassLoader 和 SharedClassLoader 的实例,否则会用到这两个类加载器的地方都会用 CommonClassLoader 的实例代替,而默认的配置文件中没有设置这两个 loader 项,所以 Tomcat 6.x 顺理成章地把/common、/server 和/shared 三个目录默认合并到一起变成一个/ lib 目录。

2.2、OSGi:灵活的类加载器架构

“学习 JEE 规范,去看 JBoss 源码;学习类加载器,就去看 OSGi 源码”。

OSGi 在 Java 程序员中最著名的应用案例就是Eclipse IDE。

一个 Bundle 可以声明它所依赖的 Java   Package( 通过 Import- Package 描述),也可以声明它允许导出发布的 Java   Package( 通过 Export- Package 描述)。

一个模块里只有被 Export 过的 Package 才可能由外界访问。

基于 OSGi 的程序很可能(只是很可能,并不是一定会)可以实现模块级的热插拔功能,当程序升级更新或调试除错时,可以只停用、重新安装然后启用程序的其中一部分。

OSGi 的 Bundle 类加载器之间只有规则,没有固定的委派关系。

只有具体使用某个 Package 和 Class 的时候,才会根据 Package 导入导出定义来构造 Bundle 间的委派和依赖。

如果一个类存在于 Bundle 的类库中但是没有被 Export, 那么这个 Bundle 的类加载器能找到这个类,但不会提供给其他 Bundle 使用

并非所有的应用都适合采用 OSGi 作为基础架构, OSGi 在提供强大功能的同时,也引入了额外的复杂度,带来了线程死锁和内存泄漏的风险。

2.3、字节码生成技术与动态代理的实现

javac 也是一个由 Java 语言写成的程序,它的代码存放在 OpenJDK 的 langtools/src/share/classes/com/ sun/tools/javac 目录中[ 1]。 要深入了解字节码生成,阅读 javac 的源码是个很好的途径。

动态代理实现了可以在原始类和接口还未知的时候,就确定代理类的代理行为,当代理类与原始类脱离直接联系后,就可以很灵活地重用于不同的应用场景之中。调用了 sun.misc.ProxyGenerator.generateProxyClass() 方法来完成生成字节码的动作,这个方法可以在运行时产生一个描述代理类的字节码 byte[] 数组。

2.4、Retrotranslator:跨越JDK版本

一种名为“ Java 逆向移植”的工具( Java Backporting Tools)应运而生, Retrotranslator[1] 是这类工具中较出色的一个。

编译器在程序中使用到`包装对象`的地方自动插入了很多 Integer.valueOf()、 Float.valueOf() 之类的代码;`变长参数`在编译之后就自动转化成了一个数组来完成参数传递;`泛型`的信息则在编译阶段就已经擦除掉了(但是在元数据中还保留着),相应的地方被编译器自动插入了类型转换代码[ 2]。

从字节码的角度来看,`枚举`仅仅是一个继承于 java. lang. Enum、 自动生成了 values() 和 valueOf() 方法的普通 Java 类而已。

3、实战:自己动手实现远程执行功能
3.1、目标
3.2、思路
3.3、实现

构造函数中指定为加载 HotSwapClassLoader 类的类加载器作为父类加载器,这一步是实现提交的执行代码可以访问服务端引用类库的关键。

3.4、验证
4、本章小结
除了文章中有特别说明,均为IT宅原创文章,转载请以链接形式注明出处。
本文链接:http://www.itzhai.com/class-loader-execute-subsystem-analyze.html
关键字: ,
arthinking Java技术交流群:280755654,入门群:428693174 more
分享到:
 
2015 3/1
文章评论
    没有评论
给我留言

有人回复时邮件通知我
未分类的相关文章
随机文章 本月热门 热评
1 Javascript中加号运算符的二义性注意事项 2012/4/28
2 任何不以学习知识为目的的考试都是耍流氓-操作系统试题 2011/7/3
3 Android开发环境的基本配置过程 2011/7/12
4 C语言语法笔记 – 结构体变量与共用体 2011/8/30
5 org.hibernate.LazyInitializationException的解决方法 使用OpenSessionInViewFilter 2011/7/31
6 Java Web笔记 – JavaBean的使用 JavaBean的范围 与Java代码的交互 2011/11/10
友情推荐 更多
破博客 文官洗碗安天下,武将打怪定乾坤。多么美好的年代,思之令人泪落。
Mr.5's Life 白天是一名程序员,晚上就是个有抱负的探索者
行知-追寻技术之美 关注大数据,分布式系统
我爱编程 编程成长轨迹
Cynthia's Blog 学习笔记 知识总结 思考感悟
 
猜您喜欢
欢迎关注我的公众号 IT宅
关于IT宅 文章归档

IT宅中的文章除了标题注明转载或有特别说明的文章,均为IT宅的技术知识总结,学习笔记或随笔。如果喜欢,请使用文章下面提供的分享组件。转载请注明出处并加入文章的原链接。 感谢大家的支持。

联系我们:admin@itzhai.com

Theme by arthinking. Copyright © 2011-2015 IT宅.com 保留所有权利.