`
zy19982004
  • 浏览: 654942 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
博客专栏
F6f66edc-1c1a-3859-b76b-a22e740b7aa7
Hadoop学习
浏览量:250057
社区版块
存档分类
最新评论

Java ClassLoader学习四:ContextClassLoader

 
阅读更多

 

一.ContextClassLoader

  1. ContextClassLoader只是一个逻辑上的概念,在Java Api里并没有一个叫ContextClassLoader的类。
  2. JVM默认类加载体系已经能满足大部分情况的使用了,那为什么还需要ContextClassLoader呢。但有时候这样的加载体系并不能满足要求,比喻需要动态加载应用程序开发人员提供的资源时。考虑JDBC的实现,JDK中的JDBC Api是由BootStrap加载的,当我们确定使用某一厂商的JDBC实现时,实现类也会由BootstrapLoader加载,显然BootstrapLoader是加载不了的。于是就出现了ContextClassLoader这个概念。JDBC Api里使用ContextClassLoader去加载实现类,默认情况ContextClassLoader就是AppClassLoader(参考http://zy19982004.iteye.com/blog/1983236),刚好可以加载位于classpath下的实现类。
  3. 再说的清楚一点,ContextClassLoader就是Thread的一个属性,提供了get和set方法,因此任何地方都可以设置并获得这个ClassLoader。
    private ClassLoader contextClassLoader;
  4. 在没有显示setContextClassLoader的时候,getContextClassLoader默认返回的是该线程的父线程的ClassLoader。
    public void setContextClassLoader(ClassLoader cl){}
    public ClassLoader getContextClassLoader() {}
  5. 其实还有一个办法,把AppClassLoader保存起来,当BootstrapLoader加载不到实现类时,用AppClassLoader去加载。

二.学习例子

package com.jyz.study.jdk.classLoader;

import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;

/**
 *  演示ContextClassLoader的使用
 *  @author JoyoungZhang@gmail.com
 *  
 */
public class ContextClassLoaderTest {
    
	public static void main(String[] args) throws MalformedURLException, ClassNotFoundException {
		System.out.println("MainClass getClassLoader: " + ContextClassLoaderTest.class.getClassLoader());
		System.out.println("MainClass getContextClassLoader: " + Thread.currentThread().getContextClassLoader());
		Thread innerThread1 = new InnerThread1();
		innerThread1.start();
	}
	
}

class InnerThread1 extends Thread{
	@Override
	public void run() {
		try {
			URL[] urls = new URL[1];
			urls[0] = new URL("jar:file:/E:/GoogleCode/platform-components/trunk/SourceCode/component-core/target/component-core-1.0.jar!/");
			URLClassLoader urlClassLoader = new URLClassLoader(urls);
			Class<?> clazz = urlClassLoader.loadClass("com.jyz.component.core.collection.Tuple");
			System.out.println(clazz.newInstance());
			
			System.out.println("InnerThread1 getClassLoader: " + clazz.getClassLoader());
			System.out.println("InnerThread1 getContextClassLoader: " + Thread.currentThread().getContextClassLoader());
			
			this.setContextClassLoader(urlClassLoader);
			
			Thread innerThread2 = new InnerThread2();
			innerThread2.start();
		}catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}
	}
}


class InnerThread2 extends Thread{
	@Override
	public void run() {
		try {
			ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
			classLoader.loadClass("com.jyz.component.core.collection.Triple");
			System.out.println("InnerThread2 getContextClassLoader: " + Thread.currentThread().getContextClassLoader());
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
}


console output:
MainClass getClassLoader: sun.misc.Launcher$AppClassLoader@f6a746
MainClass getContextClassLoader: sun.misc.Launcher$AppClassLoader@f6a746
Tuple[t1:null, t2:null]
InnerThread1 getClassLoader: java.net.URLClassLoader@f9f9d8
InnerThread1 getContextClassLoader: sun.misc.Launcher$AppClassLoader@f6a746
InnerThread2 getContextClassLoader: java.net.URLClassLoader@f9f9d8


注释掉36行时console output:
MainClass getClassLoader: sun.misc.Launcher$AppClassLoader@f6a746
MainClass getContextClassLoader: sun.misc.Launcher$AppClassLoader@f6a746
Tuple[t1:null, t2:null]
InnerThread1 getClassLoader: java.net.URLClassLoader@f9f9d8
InnerThread1 getContextClassLoader: sun.misc.Launcher$AppClassLoader@f6a746
java.lang.ClassNotFoundException: com.jyz.component.core.collection.Triple
...异常栈信息

 

1
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics