线程上下文类加载器本质剖析与实做
1. 线程上下文类加载器
-
线程上下文类加载器默认是系统类加载器,主要是因为:在Launcher类中:
Thread.currentThread().setContextClassLoader(this.loader); 在创建完加载器之后,直接将就loader作为参数放进去了
-
实例一:
-
public class MyTest25 implements Runnable{ private Thread thread; public MyTest25(){ thread = new Thread(this); thread.start(); } @Override public void run() { ClassLoader classLoader = this.thread.getContextClassLoader(); this.thread.setContextClassLoader(classLoader); System.out.println("Class: "+classLoader.getClass()); System.out.println("Parent: "+classLoader.getParent().getClass()); } public static void main(String[] args) { new MyTest25(); } } 运行结果: Class: class sun.misc.Launcher$AppClassLoader //线程上下文类加载器默认是系统类加载器 Parent: class sun.misc.Launcher$ExtClassLoader
-
2.线程上下文类加载器的一般使用模式(获取 — 使用 — 还原)
ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); //获取
try{
Thread.currentThread.setContextClassLoader(targetTccl); //设置
myMethod(); //使用
}finally{
Thread.currentThread.setContextClassLoader(classLoader); //还原
}
-
总结:
- myMethod里面则调用了Thread.currentThread().getContextClassLoader(),获取当前线程的上下文类加载器做某些事情。
- 如果一个类由类加载器A加载,那么这个类的依赖类也是由相同的类加载器加载的(如果该依赖类之前没有被加载器过的话)
- ★ContextClassLoader的作用就是为了破坏Java的类加载委托机制。
- ★当高层提供了统一的接口让底层去实现,同时又要在高层加载(或实例化)底层的类时,就必须要通过线程上下文类加载器来帮助高层的ClassLoader找到并加载该类。