Thread.getContextClassLoader与Thread.getClassLoader()区别

在阅读spring boot启动时候的源码中,发现获取classLoader使用的是getContextClassLoader于是乎产生了疑问,这种获取ClassLoader的方式与我们最常见的通过Class.getClassLoader二者有什么区别?都是在什么场景下使用呢?

首先来看看getClassLoader()方法的注释:

Returns the class loader for the class. Some implementations may use null to represent the bootstrap class loader. This method will return null in such implementations if this class was loaded by the bootstrap class loader.

 主要的意思是getClassLoader()返回该类的类加载器,如果是bootstrap加载器加载的类返回Null,这种机制主要是为了安全考虑bootstrap是用来加载jvm核心库的加载器不允许暴露给用户操作,可能会引起类冲突的问题。

再来看一下getContextClassLoader()方法的说明:

Sets the context ClassLoader for this Thread. The context ClassLoader can be set when a thread is created, and allows the creator of the thread to provide the appropriate class loader, through getContextClassLoader, to code running in the thread when loading classes and resources.

这个方法返回叫线程上下文类加载器。这个加载器的类型指定的工作交给了线程创建者,创建者在创建线程之后用对应的setContextClassLoader()方法将适合的类加载器设置到线程中,那么线程中的代码就可以通过getContextClassLoader()获取到这个类加载器来加载类或者资源。如果不设置默认是系统类加载器就是 app ClassLoader()。

那么这个getContextLoader()方法在什么场景下使用呢? 因为很多框架为了做类的隔离会通过不同的ClassLoader来做类的隔离。假设框架提供了一个可扩展的服务接口这个接口的类加载器是app ClassLoader,但是这个接口是现实则交给使用者来扩展,那么实现类很有可能被自定义的ClassLoader加载导致appClassLoader无法找到实现类。如果在框架的层面希望能够获取到接口实现类就需要将实现类用getContextClassLoader获得的ClassLoader来加载。

总之,getContextClassLoader是原有代理类加载模式的一种补充。提供一种在子ClassLoader加载的类中获取父ClassLoader的实例来操作父加载器加载类的方法。

你可能感兴趣的:(JAVA)