getContextClassLoader()解决的问题
类加载器的双亲委派模型存在以下缺陷,若有下述委派链:
ClassLoader A -> System ClassLoader -> Extension ClassLoader -> Bootstrap ClassLoader
委派链左边的ClassLoader能够加载右边ClassLoader加载的类。反之,右边的ClassLoader不能访问左边ClassLoader加载的类。
Thread.currentThread().getContextClassLoader()方法就是用来解决这个问题的。它通过将某个位于委派链左边的类加载器设置为线程的ContextClassLoader,这样使得委派链右边的类加载器也能访问到左边类加载器加载的类。
getContextClassLoader()的实际运用
SPI(Service Provider Interface),是Java提供的一套被用来被第三方实现或扩展的API。它是面向扩展的,可以用来启用框架扩展和替换组件。例如:JDBC。
位于java.sql包下的DriverManager类是由启动类加载器加载的,它用来加载驱动类。而驱动类的具体实现是产商实现的,由系统类加载器加载。这样的话,启动类加载器无法获取到系统类加载器加载的类。
为了解决这个问题,启动类加载器需要将加载驱动类的具体实现类的工作交给系统类加载器。使用getContextClassLoader()就可以实现这个工作。