zoukankan      html  css  js  c++  java
  • 线程上下文类加载器分析与实现

    在上一次【https://www.cnblogs.com/webor2006/p/9246850.html】分析源码中发现有两处设置线程上下文类加载器的代码,如下:

    因为它是非常重要的东东,所以这次专门对它进行主题展开,主要的作用为了改变委托双亲模式在某些场景不太适用或者是无法满足需求的,下面先写一个简单的测试代码:

    那输出是啥呢?

    也就是说当前线程的上下文类加载器是应用类加载器,而第二输出null不足为奇,因为Thread是JDK中的系统类当然是由启动类加载器加载喽。

    对于上面的例子先有一个初浅的认识既可,在正式介绍线程的上下文类加载器之前需要介绍一些理论性的东东,只有明白了它的背景这样才能更好的掌握它,具体如下:

    • 当前类加载器(Current ClassLoader):每一个类都会使用自己的类加载器(既加载自身的类加载器)来去加载其它类(指的是所依赖的类),如果ClassX引用了ClassY,那么ClassX的类加载器就会加载ClassY(前提是ClassY尚未被加载)。
    • 线程上下文类加载器(Context ClassLoader):线程上下文类加载器是从JDK1.2开始引入的,类Thread中的getContextClassLoader()与setContextClassLoader(ClassLoader cl)分别用来获取和设置上下文类加载器。如果没有通过setContextClassLoader(ClassLoader cl)进行设置的话,线程将继承其父线程的上下文类加载器。Java应用运行时初始线程的上下文类加载器是系统类加载器【所以这也是为啥上面的第一行输出是系统类加载器的原因之所在】。在线程中运行的代码可以通过该类加载器来加载类与资源。
    • 线程上下文类加载器的重要性:
      我们在使用JDBC操作数据库时会如下进行编写:

      咱们来反思一下:JDBC是一个标准,这就说明图中使用到的Connection和Statement都是内置在JDK当中的标准,如下:


      可见都是抽象接口,而且是位于rt.jar中,其实现肯定是由不同的数据库厂商来实现,那么问题就来了:这些标准都是由根类加载器所加载的,但是具体的实现是由具体的厂商来做的,那肯定是需要将厂商的jar放到工程的classpath当中来进行使用,很显然厂商的这些类是没办法由启动类加载器去加载,会由应用类加载器去加载,而根据“父类加载器所加载的类或接口是看不到子类加载器所加载的类或接口,而子类加载器所加载的类或接口是能够看到父类加载器加载的类或接口的”这一原则,那么会导致这样一个局面:比如说java.sql包下面的某个类会由启动类加载器去加载,该类有可能会要访问具体的实现类,但具体实现类是由应用类加载器所加载的,java.sql类加载器是根据看不到具体实现类加载器所加载的类的,这就是基于双亲委托模型所出现的一个非常致命的问题,这种问题不仅是在JDBC中会出现,在JNDI、xml解析等SPI(Service Provider Interface)场景下都会出现的,所以这里总结一下:父ClassLoader可以使用当前线程Thread.currentThread().getContextLoader()所指定的ClassLoader加载的类,这就改变了父ClassLoader不能使用子ClassLoader或者其它没有直接父子关系的ClassLoader加载的类的情况,既改变了双亲委托模型。线程上下文类加载器就是当前线程的Current ClassLoader。在双亲委托模型下,类加载是由下至上的,既下层的类加载器会委托上层进行加载。但是对于SPI来说,有些接口是Java核心库所提供的,而Java核心库是由启动类加载器来加载的,而这些接口的实现去来自于不同的jar包(厂商提供)。Java的启动类加载器是不会加载其它来源的jar包,这样传统的双亲委托模型就无法满足SPI的要求。而通过给当前线程设置上下文类加载器,就可以由设置的上下文类加载器来实现对于接口实现类的加载。

    这些理论是非常之重要的,了解之后进一步学习打下坚实的基础~

  • 相关阅读:
    Idea安装Scala插件(转)
    serialVersionUID的作用(转)
    [转]学习win10的bash使用ssh连接远程服务器
    [转]使用 Travis CI 部署你的 Hexo 博客
    【转】H5
    【转】Virtual DOM
    【转】hexo博客图片问题
    【转】V8 之旅: 垃圾回收器
    关于react-redux中Provider、connect的解析
    【转】webpack4
  • 原文地址:https://www.cnblogs.com/webor2006/p/9248621.html
Copyright © 2011-2022 走看看