自定义classloader示例
public class ClTest {
/**
* @param args
*/
public static void main(String[] args) throws Exception {
//classloader1
ClassLoader classLoader1 = defCl("D:/tmp/classes");
runClTest(classLoader1);
}
private static void runClTest(ClassLoader classLoader1)
throws ClassNotFoundException, NoSuchMethodException,
InstantiationException, IllegalAccessException,
InvocationTargetException {
// 使用loadClass方法加载class,这个class是在urls参数指定的
Class<?> clazz = classLoader1.loadClass("com.taobao.cl.module.User");
System.out.println("clazz_cl=" + clazz.getClassLoader());
System.out.println("parent_clazz_cl=" + classLoader1.getParent());
// 构造对象
Constructor<?> constructor = clazz.getDeclaredConstructor(new Class[] {int.class, String.class });
Object instance = constructor.newInstance(12, "lilei");
// 然后我们就可以用反射做些事情了
Method taskMethod = clazz.getMethod("sayHello", new Class[] { String.class });
taskMethod.invoke(instance, new Object[] { "jack" });
System.out.println("---------------------");
System.out.println("success");
System.out.println("ClTest_cl=" + ClTest.class.getClassLoader());
System.out.println("User_cl=" + instance.getClass().getClassLoader());
}
private static ClassLoader defCl(String file) throws Exception{
URL jarUrl = new File(file).toURI().toURL();
System.out.println("url=" + jarUrl);
URL[] urls = new URL[] { jarUrl };
URLClassLoader cl = new URLClassLoader(urls);
return cl;
}
}
输出结果
D:\java_tools\tmp_tools\ws\simple\target\classes>java com.hy.cl.ClTest
url=file:/D:/tmp/classes/
clazz_cl=java.net.URLClassLoader@16de49c
parent_clazz_cl=sun.misc.Launcher$AppClassLoader@1bd7848
Hello jack,i am 12,my name is lilei
---------------------
success
ClTest_cl=sun.misc.Launcher$AppClassLoader@1bd7848
User_cl=java.net.URLClassLoader@16de49c
-------------------------------------------
D:\java_tools\tmp_tools\ws\simple\target\classes>java com.hy.cl.ClTest
url=file:/D:/tmp/classes/
clazz_cl=sun.misc.Launcher$AppClassLoader@1bd7848
parent_clazz_cl=sun.misc.Launcher$AppClassLoader@1bd7848
Hello jack,i am 12,my name is lilei
---------------------
success
ClTest_cl=sun.misc.Launcher$AppClassLoader@1bd7848
User_cl=sun.misc.Launcher$AppClassLoader@1bd7848
可以看出2次输出结果的区别吗?工程的当前classpath路径下存在com.hy.cl.module.User,如果不删除,那么自定义的loader的父loader会优先加载之,即出现后面的一种情况,类User的loader都是App。当我删除后,类User的loader即为自定义loader.
再增加一个自定义loader,用来加载同样的类User
//classloader2
ClassLoader classLoader2 = defCl("D:/tmp/classes");
runClTest(classLoader2);
输出结果:
D:\java_tools\tmp_tools\ws\simple\target\classes>java com.hy.cl.ClTest
url=file:/D:/tmp/classes/
clazz_cl=java.net.URLClassLoader@1f6226
parent_clazz_cl=sun.misc.Launcher$AppClassLoader@1bd7848
Hello jack,i am 12,my name is lilei
---------------------
success
ClTest_cl=sun.misc.Launcher$AppClassLoader@1bd7848
User_cl=java.net.URLClassLoader@1f6226
==============================
url=file:/D:/tmp/classes/
clazz_cl=java.net.URLClassLoader@76fba0
parent_clazz_cl=sun.misc.Launcher$AppClassLoader@1bd7848
Hello jack,i am 12,my name is lilei
---------------------
success
ClTest_cl=sun.misc.Launcher$AppClassLoader@1bd7848
User_cl=java.net.URLClassLoader@76fba0