深入理解Java虚拟机:Tomcat、OSGi类加载器架构

Tomcat:正统地类加载器架构

Tomat目录结构

可以设置3组目录(/common/*,/server/*和/shared/*),Web应用程序自身的"/WEB-INF/*"目录:

1.common目录:可以被Tomcat和所有的Web应用程序共同使用

2.server目录:可以被Tomcat使用,对所有的Web应用程序都不可见。

3.shared目录:可以被所有的Web应用程序共同使用,但对Tomcat自己不可见。

4.WEB-INF目录:可以被该Web应用程序使用,对Tomcat和其他Web应用都不可见。

Tomcat类加载器架构图

Tomcat加载类架构图

Common加载器、Catalina类加载器、Shared类加载器、Webapp类加载器分别对应加载的目录为:/common/*,/server/*,/shared/*和/WEB-INFO/*中的Java类库。

Webapp类加载器和JSP类加载器通常会有多个实例,每个Web应用程序对应一个Webapp类加载器,每个JSP文件对应一个JapserLoader类加载器。

Tomcat 6之后,简化了目录结构。/common,/server和/shared目录合成了1个/lib目录。

OSGi:灵活的类加载器架构

OSGi(Open Service Gateway Initiative)一个基于Java语言的动态模块化规范。

OSGi中的每个模块(Bundle)与普通的Java类库区别不大,都是以JAR格式封装,并内部存储的都是Java的Package和Class。但是一个Bundle可以声明它所依赖的Package,也可以声明它允许导出发布的Package。

Bundle之间的依赖关系从传统的上层模块依赖底层转变为平级模块之间的依赖,而且类库的可见性得到精确的控制,一个模块里只有被Export过的Package才可能被外部访问,其他的Package和Class将被隐藏起来。

基于OSGi架构的程序可能会实现模块机的热插拔功能,当程序升级更新或调试时,可以只停用、重新安装然后启用程序的一部分,如Eclipse中安装、卸载、更新插件不需要重启动

OSGi类加载器架构图

1.以java.*开头的类,委派给父类加载器加载。

2.委派列表名单为的类,委派给父类加载器加载。

3.Import列表中的类,委派给Export这个类的Bundle的类加载器加载。

4.查找当前Bundle的Classpath,使用自己的类加载器加载

5.查找是否存在自己的Fragment Bundle中,如果是则委派给Fragment Bundle的类加载器加载。

6.查找Dynamic Import列表的Bundle,委派给对应的Bundle的类加载器加载。

7.类查找失败

缺点

1.在高并发的情况下,如果Bundle A依赖Bundle B的Package B,而Bundle B又依赖Bundle A的Package B的类,会发生死锁。

2.JDK 7中在ClassLoader中增加了registerAsParallelCapable方法对并行的类加载进行了注册声明,把所的级别从ClassLoader对象,降低为要加载的对应的类级别。

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20200504A0P0UG00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券