日期:2014-05-20  浏览次数:20714 次

Thread的getContextClassLoader()
忘记以前有没有问过这个问题,总之我现在有看到几个地方有这个:
Thread.currentThread().getContextClassLoader()
我总是想不出在什么情况下会用这种方式获得一个ClassLoader,因为好像默认情况下,它返回的是和加载应用的ClassLoader是同一个,比如说在一个类Test中写
ClassLoader cl = Thread.currentThread().getContextClassLoader();
为何不直接用Test.class.getClassLoader()

获得当前上下文的类加载器是啥意思?有啥好处?

------解决方案--------------------
http://stackoverflow.com/questions/676250/different-ways-of-loading-a-file-as-an-inputstream
------解决方案--------------------
http://uule.iteye.com/blog/813841
------解决方案--------------------
假设要装载的类,通过当前类的Classloader链装载不了,那就得设ContextClassLoader
------解决方案--------------------
通过当前类的Classloader链装载不了,那就得设ContextClassLoader
------解决方案--------------------

public class Test {

public static void main(String[] args) {

// 此时三个ClassLoader是同一个对象
System.out.println(Thread.currentThread().getContextClassLoader()); // 当前线程的类加载器
System.out.println(Test.class.getClassLoader()); // 当前类的类加载器
System.out.println(ClassLoader.getSystemClassLoader()); // 系统初始的类加载器

}
}

如果楼主了解过openfire应该对ClassLoader有比较深的理解。
打个简单的比方,你一个WEB程序,发布到Tomcat里面运行。
首先是执行Tomcat org.apache.catalina.startup.Bootstrap类,这时候的类加载器是ClassLoader.getSystemClassLoader()。
而我们后面的WEB程序,里面的jar、resources都是由Tomcat内部来加载的,所以你在代码中动态加载jar、资源文件的时候,首先应该是使用Thread.currentThread().getContextClassLoader()。如果你使用Test.class.getClassLoader(),可能会导致和当前线程所运行的类加载器不一致(因为Java天生的多线程)。
Test.class.getClassLoader()一般用在getResource,因为你想要获取某个资源文件的时候,这个资源文件的位置是相对固定的。

建议楼主去查看一下openfire或者tomcat内部的源码,对ClassLoader会有比较深的理解。
在openfire里面,openfire使用的类加载器,以及每个插件使用的类加载器都不一样。

------解决方案--------------------

final ClassLoader parent = findParentClassLoader();

            String libDirString = System.getProperty("openfire.lib.dir");

            File libDir;
            if (libDirString != null) {
                // If the lib directory property has been specified and it actually
                // exists use it, else use the default
                libDir = new File(libDirString);
                if (!libDir.exists()) {
                    Log.warn("Lib directory " + libDirString +
                            " does not exist. Using default " + DEFAULT_LIB_DIR);
                    libDir = new File(DEFAULT_LIB_DIR);
                }
            }
            else {
                libDir = new File(DEFAULT_LIB_DIR);
            }

            // Unpack any pack files.
            unpackArchives(libDir, true);

            String adminLibDirString = System.getProperty("openfireHome");
            if (adminLibDirString == null) {
                adminLibDirString = DEFAULT_ADMIN_LIB_DIR;
            }
            else {
                adminLibDirString = adminLibDirString+"/plugins/admin/webapp/WEB-INF/lib";
            }
            File adminLibDir = new File(adminLibDirString);
            if (adminLibDir.exists()) {