tomcat加载配置时加载到jdbc就停止加载_主流web容器类加载机制

cdd8267fb5642e0b31034f54fc8ac64c.gif

前言

由java类加载机制和类加载器(classLoader)文章我们知道,java默认的类加载机制是通过双亲委派模式实现的。如果一个类加载器收到了类加载请求,它并不会自己先去加载,而是把这个请求委托给父类的加载器去执行,如果父类的加载器还存在父类加载器,则进一步向上委托,依次递归,最终将到达顶层的启动类加载器,如果父类加载器可以完成类加载任务,就成功返回,倘若父类加载器无法完成加载任务,子加载器才会尝试自己加载。

cd7d23e1277ceedc390fb6cfc7a6c656.png

对于运行在java EE 容器中的web应用来说,类加载器的实现方式与一般的java应用有所不同。不同的web容器的实现方式也会有所不同。今天我们来讲讲主流web 容器tomcat和weblogic类加载机制的实现方式。

tomcat类加载器

tomcat 作为一个java web容器,也有自己的类加载机制,通过自定义的类加载机制以实现共享类库的抽取,不同web应用之间的资源隔离还有热加载等功能。除了java自身的类加载之外,它主要实现的类加载器主要有:Common ClassLoader,Catalina ClassLoader,Shared ClassLoader,WebApp ClassLoader以及JasperLoader。

03eaf540f8448c724764105ce86e2c82.png

从图中的委派关系可以看出:Common类加载器能加载的类都可以被Catalina类加载器Shared类加载器使用,从而实现了公有类库的共用,而Catalina类加载器Shared类加载器自己能加载的类则与对方相互隔离,属于兄弟关系。WebApp类加载器可以使用Shared类加载器加载到的类,但各个WebApp类加载器实例之间相互隔离。而JasperLoader的加载范围仅仅是这个JSP文件所编译出来的那一个.class文件,它出现的目的就是为了被丢弃:当Web容器检测到JSP文件被修改时,会替换掉目前的JasperLoader的实例,并通过再建立一个新的Jsp类加载器来实现JSP文件的HotSwap功能。

为啥这样设计,我们先了解下每个类加载器的用途:

  • Common类加载器:负责加载tomcat和web应用都复用的类。
  • Catalina类加载器:负责加载tomcat专用类,而这些被加载的类在web应用中不可见。
  • Shared类加载器:负责加载tomcat下所有的web应用程序都复用的类,而这些被加载的类在tomcat中不可见。
  • WebApp类加载器:负责加载具体的某个Web应用程序所使用到的类,而这些被加载的类在Tomcat和其他的Web应用程序都将不可见。
  • Jsp类加载器:每个jsp页面一个类加载器,不同的jsp页面有不同的类加载器,方便实现jsp页面的热插拔。

双亲委派机制存在一种缺陷,基础类加载器只能加载自己指定范围内的类,对于用户提供的类是没办法加载的,以至于如果基础类需要用户类,那就没办法加载。比如JDBC,我们都知道这是java提供的一种规范,由不同的厂商去实现。规范是通过接口体现,作为基础类。而厂商的实现是驱动包,放在项目的依赖包中。我们可以使用DriverManager.getConnection()去获取连接,使用Class.forName()去加载驱动。如果严格按照双亲委派机制,DriverManager是java.sql包中的,属于BootStrapClassLoader的范围,它只能看到这个文件夹中的类,而我们的驱动包是不在这里面的,就无法找到类,也就没法去加载了。

tomcat为了实现隔离性,破坏了双亲委派机制,每个web应用都有一个对应的类加载器实例。该类加载器使用代理模式,它首先尝试去加载class,如果找不到再代理给父类加载器。这样就使得web应用自己的类优先级高于web容器提供的类,保证每个应用程序的类库是相互独立的,并且相互隔离。

weblogic 类加载器

weblogic中classloader是分层次的,它只能加载比它层次高的类及它自身的类,同层次的类及比它层次低的类都不能加载

  1. JDK Classloader
  2. JDK ext Class Loader
  3. Weblogic System Class Loader
  4. Domain Class Loader(Child of System Class Loader)
  5. App Class Loader (负责装载应用中的所有的EJB JAR文件)
  6. Web Class Loader (负责装载所有的Web application 中的WAR文件(所有得jsp文件除外)
  7. JSP Class Loader (负责装载Web application 中的所有的jsp文件)

注意:第6条,先加载classes中的类,再加载lib中的类,当然也可以通过修改Weblogic.xml修改加载顺序。

由上面可知:App Class Loader不能实例化Web application下的类,否则会报类找不到的错误。

当部署一个应用的时候,weblogic server 会自动创建一个具有层次结构的类装载器:

  1. Application Classloader负责装载应用中的所有的EJB JAR文件;
  2. Web Application Classloader负责装载所有的Web application 中的WAR 文件(所有得jsp文件除外);
  3. Jsp Classloader 负责装载Web application 中的所有的jsp 文件。

在Weblogic服务启动的过程中,自动形成一个具有层次结构的类装载器,首先装载jdk及java扩展jar包或类;然后再加载Weblogic本身使用的各个jar包或类;然后再加载Web应用文件夹里面的classes下的类,然后再加载Web应用文件夹里面lib下的jar包或类。也就是说,每个层次的类装载器均对应不同的类路径,它们是一一对应的。 比如System装载器对应着jdk及扩展路径;Application装载器对应着Weblogic的相关类;而web 应用装载器对应着webapp应用下的classes和lib下的路径;而jsp装载器则对应着jsp文件。

当然,在加载过程中,若在高层次的加载器中已经加载了某类,那么再以后的加载中,再次遇到该类也不会加载,只是会忽略。加载完成之后,将类放入Cache中供系统应用调用。

在系统的运行过程中,若遇到使用该类的情况,则会遵循双亲委派机制,先通过其父类加载器进行加载的原则,比方说,我要加载一个WSWordManager类,则系统会首先在Cache中寻找,若找不到,则调用父装载器到与之对应的路径里面去寻找,一直向上,找着了则进行加载,若找不着则报出ClassNotFound的异常。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值