1.Tomcat:正统的类加载器架构
一个功能健全的web服务器,要解决如下问题:
1.部署在同一个服务器上的两个web应用程序所使用的的java类库应该可以隔离。(可能依赖的版本不同)
2.部署在同一个服务器上的两个web应用程序所使用的的java类库应该可以共享。(避免资源浪费和内存膨胀)
3.服务器应尽可能保证自身安全不受部署的应用程序的影响。(服务器使用的类库应与应用程序使用的类库相互独立)
4.支持jsp应用的web服务器,大多数需支持hotswap功能。
tomcat中,通过按照双亲委派模型实现了多个类加载器,来支持类库之间的加和隔离。
Tomcat6.x版本,只有指定了tomcat/conf/catalina.properties配置文件中的server.loader和share.loader项后才会真正建立CatalinaClassLoader和SharedClassLoader的实例,否则默认用到这两个类加载器的地方会用CommonClassLoader的实例代替。所以tomcat6.x版本将/common、/server和/shared目录放在一起,合并为/lib,相当于以前中的/common
2.OSGi:灵活的类加载器架构
OSGi(Open Service GateWay Initiative)是由OSGi联盟制定的一个基于java语言的动态模块化规范。
OSGi一个有名的应用案例就是Eclipse IDE,此外还有许多大型软件平台和中间件服务器都基于或声明将基于OSGi规范来实现。
OSGi中每个模块(Bundle)的形式与java类库区别不大,一般都以JAR格式进行封装,内部存储的都是java package和class。但,
1)Bundle可声明它依赖的java package(通过Import-Package描述),也可声明它允许导出发布的java-package(通过Export-Package描)。
2)一个Bundle里只有被export过的package才能被外界访问(精确的模块划分和可见性控制,从而基于OSGi的程序很可能可以实现模块的热插拔功能)。
3)Bundle类加载器之间只有规则,没有固定的委派关系(更加灵活)。
若一个Bundle声明了它依赖的package,且这个package被其他bundle发布,那么所有对该package的类加载动作,均会委派给发布它的bundle类加载器来完成。
OSGi中,加载器之间的关系不再是双亲委派模型中的树形结构,而是变成了更复杂、运行时才能确定的网状结构,因此bundle间可能会形成相互依赖关系,从而可能会导致线程的死锁。