基础知识点

知识点1: 每个ClassLoader都只能加载自己所绑定目录下的资源;
知识点2: 加载资源时的ClassLoader可以有多种选择:
   1. 系统类加载器SystemClassLoader,可通过ClassLoader.getSystemClassLoader()获得;
   2. 当前ClassLoader:加载了当前类的ClassLoader;
   3. 线程上下文类加载器ContextClassLoader:Thread.currentThread().getContextClassLoader();
   4. 自定义类加载器;

ContextClassLoader作用

  加载类或资源的手段之一,只不过在一些场景下成为了唯一可选手段,从而显得特别重要,比如在JDK的SPI接口中加载SPI实现类,插件的加载等,下面以JDBC驱动的加载过程为例进行说明。

JDBC驱动的加载过程

应用程序加载驱动的方式如下:
类加载机制之ContextClassLoader

  1. 调用Class.forName()加载mysql的驱动,由于调用类SpiTest在classpath路径上,因此使用使用SystemClassLoader加载类”com.mysql.jdbc.Driver”;
  2. 加载过程中会执行static语句块,将驱动实例注册到DriverManager中,此时会涉及到DriverManager类的加载,如下图所示:
    类加载机制之ContextClassLoader
  3. DriverManager类的加载也会执行static语句块,逻辑是使用ServiceLoader机制加载各种JDBC驱动,如下图所示:
    类加载机制之ContextClassLoader
  4. 最终调用ServiceLoader.load()方法加载驱动,此时就只能使用ContextClassLoader进行加载,如下图所示:
    类加载机制之ContextClassLoader
    原因是:当前类加载器(DriverManager类的加载器)为启动类加载器,只能加载JDK核心类,当然也无法在JDK中创建自定义的ClassLoader,因此可选的ClassLoader只有两种,即SystemClassLoader和ContextClassLoader。但是SystemClassLoader只能加载classpath路径下的驱动,有局限性。ContextClassLoader没有局限性,可以在应用程序中将其设为任意ClassLoader,加载任意目录下的类和资源,如下图所示:
    类加载机制之ContextClassLoader

相关文章:

  • 2021-08-10
  • 2021-10-16
  • 2021-05-18
  • 2021-08-18
  • 2021-08-03
猜你喜欢
  • 2021-07-28
  • 2021-09-26
  • 2021-12-02
  • 2021-12-04
  • 2022-01-19
  • 2021-04-09
  • 2021-07-14
相关资源
相似解决方案