Current Classloader(当前类加载器)
每一个类都会使用自己的类加载器(即加载自身的类加载器) 来去加载其他类(指的是所依赖的类)
(PS: 说人话就是 用这个类的加载器去加载 它所依赖的类 例如它所继承的类 )
(PPS :再例如 A 引用了B 那么 A的类加载器 就会去加载B (前提是 B没有被加载))
Context ClassLoader (线程上下文类加载器)
类Thread中的getContextClassLoader()与 setContextClassLoader(ClassLoader
cl) 分别用来获取和设值上下文类加载器 如果没有通过setContextClassLoader(ClassLoader
cl)进行设值的话,线程将继承其父线程的上下文类加载器 JAVA
应用运行时的初始线程的上下文类加载器是系统类加载器(AppClassLoader)
在线程中运行的代码可以通过该类加载器来加载类与资源
线程上下文类加载器的重要性
SPI (Service Provider Interface) 提供服务者
父classloader可以使用当前线程Thread.currentThread().getContextLoader()
所指定的ClassLoader加载的类 这就改变了父classloader
不能使用子classloader或是其他没有直接父子关系的classLoader 加载的情况 即改变了双亲委托模型 (ps 用线程
getcontextloader 可以让父加载器去加载子加载器的类 )
线程上下文类加载器就是当前线程的CurrentClassLoader
总结
在双亲委托模型下 , 类加载是由下至上的 , 即下层的加载器会委托上层进行加载 ,对于SPI来说
有些接口是JAVA核心库所提供的而JAVA核心库是由启动类加载器来加载的
,而这些接口的实现是来自于不同的jar包(厂商的提供)JAVA的启动类加载器是不会加载其他来源的jar包
这样传统的双亲委托模型就无法满足SPI的要求 而通过给当前线程设置上下文类加载器就可以由设置的上下文类加载器来实现对接口实现类的加载(打破双亲委托模型限制)
(SPI 接口是由启动类来加载的 而是实现类是由应用类加载器 来加载的)