浅议tomcat与classloader

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅议tomcat与classloader相关的知识,希望对你有一定的参考价值。

     关于tomcat和classloader的文章,网上多如牛毛,且互相转载,所以大多数搜到的基本上是讲到了tomcat中classloader的几个层次,对于初接触classloader,看了之后还是只知其然不知其所以然。

   一直比较好奇,为什么tomcat需要实现自己的classloader,jvm提供的classloader有什么不符合需要?

   事实上,tomcat之所以造了一堆自己的classloader,大致是出于下面三类目的:

  • 对于各个webapp中的class和lib,需要相互隔离,不能出现一个应用中加载的类库会影响另一个应用的情况;而对于许多应用,需要有共享的lib以便不浪费资源,举个例子,如果webapp1和webapp2都用到了log4j,可以将log4j提到tomcat/lib中,表示所有应用共享此类库,试想如果log4j很大,并且20个应用都分别加载,那实在是没有必要的。
  • 第二个原因则是与jvm一样的安全性问题。使用单独的classloader去装载tomcat自身的类库,以免其他恶意或无意的破坏;
  • 第三个原因是热部署的问题。相信大家一定为tomcat修改文件不用重启就自动重新装载类库而惊叹吧。

   本文集中探讨第一个和第三个原因,即tomcat中如何利用classloader做到部分隔离,部分共享的,以及tomcat如何做到热部署的。

   首先,我们讨论tomcat中如何做到lib的部分隔离,部分共享的。在Bootstrap中,可以找到如下代码:

private void initClassLoaders() {
        try {
            commonLoader = createClassLoader("common", null);
            if( commonLoader == null ) {
                // no config file, default to this loader - we might be in a ‘single‘ env.
                commonLoader=this.getClass().getClassLoader();
            }
            catalinaLoader = createClassLoader("server", commonLoader);
            sharedLoader = createClassLoader("shared", commonLoader);
        } catch (Throwable t) {
            log.error("Class loader creation threw exception", t);
            System.exit(1);
        }
    }

   应该可以看出来,这里创建了3个classloader,分别是common,server和shared,并且common是server和shared之父。如果感兴趣,可以看下createClassLoader,它会调用进ClassLoaderFactory.createClassLoader,这个工厂方法最后会创建一个StandardClassLoader,StandardClassLoader仅仅继承了URLClassLoader而没有其他更多改动,也就是说上面3个classloader都是StandardClassLoader,除了层次关系之外,他们与jvm定义的classloader并没有区别,这就意味着他们同样遵循双亲委派模型,只要我们能够用它装载指定的类,则它就自然的嵌入到了jvm的classloader体系中去了。Tomcat的classloader体系如图:

 

以上是关于浅议tomcat与classloader的主要内容,如果未能解决你的问题,请参考以下文章

tomcat6-servlet规范对接 与 ClassLoader隔离

在Tomcat的安装目录下conf目录下的server.xml文件中增加一个xml代码片段,该代码片段中每个属性的含义与用途

[Tomcat] Tomcat的classloader

Tomcat 7 使用新 URL 和“类路径”字符串获取资源,ClassLoader.getSystemClassLoader().getResource 返回 null

浅议分布式链路追踪与日志的整合

浅议分布式链路追踪与日志的整合