深入理解Java虚拟机::类加载及执行子系统的案例与实战

类加载及执行子系统的案例与实战

  • Tomcat:正统的类加载器架构
    • 必要的服务器功能
      • 部署在同一个服务器上的两个 Web 应用程序所使用的 Java 类库可以实现相互隔离
      • 部署在同一个服务器上的两个 Web 应用程序所使用的 Java 类库可以互相共享。
      • 服务器需要尽可能地保证自身的安全不受部署的 Web 应用程序影响
      • 支持 JSP 应用的 Web 服务器,十有八九都需要支持 HotSwap 功能。
    • 为了满足上述需求,在部署 Web 应用时,单独的一个 ClassPath 就不能满足需求了,所以各种 Web 服务器都不约而同地提供了好几个有着不同含义的 ClassPath 路径供用户存放第三方类库,这些路径一般 会以“lib”或“classes”命名。被放置到不同路径中的类库,具备不同的访问范围和服务对象,通常每一个目录都会有一个相应的自定义类加载器去加载放置在里面的 Java 类库。
  • OSGi:灵活的类加载器架构
    • OSGi 中的每个模块(称为 Bundle)与普通的 Java 类库区别并不太大,两者一般都以 JAR 格式进行封装,并且内部存储的都是 Java 的 Package 和 Class。但是一个 Bundle 可以声明它所依赖的 Package(通过 Import-Package 描述),也可以声明它允许导出发布的 Package(通过 Export-Package 描述)。在 OSGi 里面,Bundle 之间的依赖关系从传统的上层模块依赖底层模块转变为平级模块之间的依赖,而且类库的可见性能得到非常精确的控制,一个模块里只有被 Export 过的 Package 才可能被外界访问,其他的 Package 和 Class 将会被隐藏起来。
    • 加载规则
      • 以 java.*开头的类,委派给父类加载器加载。
      • 否则,委派列表名单内的类,委派给父类加载器加载。
      • 否则,Import 列表中的类,委派给 Export 这个类的 Bundle 的类加载器加载。
      • 否则,查找当前 Bundle 的 Classpath,使用自己的类加载器加载。
      • 否则,查找是否在自己的 Fragment Bundle 中,如果是则委派给 Fragment Bundle 的类加载器加载。
      • 否则,查找 Dynamic Import 列表的 Bundle,委派给对应 Bundle 的类加载器加载。
      • 否则,类查找失败。
  • 字节码生成技术与动态代理的实现
    • 省去了编写代理类那一点编码工作量,
    • 实现了可以在原始类和接口还未知的时候,就确定代理类的代理行为,当代理类与原始类脱离直接联系后,就可以很灵活地重用于不同的应用场景之中。
  • Backport 工具:Java 的时光机器
    • ASM 框架直接对字节码进行处理,把高版本的字节码编译到更低版本的字节码