《深入理解Java虚拟机》读书笔记(八)--类加载及执行子系统案例(Tomcat类加载、OSGI、动态代理)

一、Tomcat类加载器架构

作为一个web服务器,需要解决以下几个问题:

  • 部署在同一个服务器上的web应用程序所使用的Java类库可以实现相互隔离。
  • 部署在同一个服务器上的两个web应用程序所使用的Java类库可以互相共享。
  • 服务器需要尽可能保证自身的安全不受部署的web应用程序影响。
  • JSP需要支持热更新

由于存在上述问题,单独的一个classpath无法满足需求,所以web服务器都提供了好几个classpath路径供用户存放第三方类库。在Tomcat目录结构中,有3组目录(“/common/*”、“/server/*”和“/shared/*”),再加上web应用程序自身的目录”/WEB-INF/*“。

  • /common目录:类库可被Tomcat和所有的Web应用程序共同使用。

  • /server目录:类库可被Tomcat使用,对所有的Web应用程序都不可见。

  • /shared目录:类库可被所有的web应用程序共同使用,但对Tomcat自己不可见。

  • /webapp/WEB-INF目录:类库仅可以被此微web应用程序使用,对Tomcat和其它web应用程序都不可见 。

Tomcat自定义了多个类加载器,这些类加载按照经典的双亲委派模型来实现,其关系如图所示:

Tomcat 5.x 类加载器结构(网图)

其中,顶层的启动类加载器、扩展类加载器、应用程序类加载器都是JDK默认提供的类加载器。另外的CommonClassLoader负责加载”/common/*“中的Java类库,CatalinaClassLoader负责加载”/server/*“中的Java类库,SharedClassLoader负责加载”/shared/*“中的Java类库,而WebAppClassLoader负责加载各自的”/WebApp/WEB-INF/*“中的Java类库,最后每一个jsp文件都对应一个类加载器。

注:Tomcat的6.x版本后,common、server、shared都默认合并到了lib目录,这个目录里的类库相当于以前common目录中类库起到的作用。如果默认设置不能满足要求,用户可以通过修改配置文件指定server.loader和share.loader的方式重新启用5.x的加载器结构

从上图可以看出,CommonClassLoader能加载的类都可以被CatalinaClassLoader和SharedClassLoader类加载器加载,而CatalinaClassLoader和SharedClassloader自己能加载的类则与对方相互隔离。WebClassLoader可以使用SharedClassLoader(包括上层类加载器)加载到的类,但是各个WebAppClassLoader实例之间相互隔离。而JasperLoader的加载范围仅是这个jsp文件所编译出来的那一个class,当服务器检测到jsp文件被修改时,会替换掉目前的JasperLoader实例,并通过再建立一个新的jsp类加载来实现jsp的热更新功能(关于jsp可以参考JSP是如何编译成servlet并提供服务的)。

关于违反双亲委派

上面提到了,对于web容器来说,都需要解决的一个重要问题:对于不同的webapp,各自目录下的jar包可能需要相互隔离。一个简单的例子就是部署在同一个容器下的不同应用程序可能会依赖同一jar包的不同版本,所以必须要相互隔离。要做到隔离也很简单,每个应用程序都有一个对应自己目录的类加载器,而这些jar包存放在自己应用的目录下,由各自的类加载器加载,即可做到相互隔离。但是从这个描述来说,其实并没有违反双亲

  • 54
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 19
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 19
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值