如何改變類加載的雙親委派模式

package com.stand.job.common.classload;

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

import com.stand.job.common.utils.ArrayUtils;

/**
 * 
 * @author chichaofan
 *
 *         若是delegateLoad 爲false加載順序以下
 * 
 *         bootstrapsclassload -> extclassload -> 自定義各類類加載器 -> systemclassload
 * 
 *         若是delegateLoad 爲true爲默認類加載器加載順序以下
 * 
 *         bootstrapsclassload -> extclassload ->systemclassload -> 自定義各類類加載器
 */
public class StandJobClassLoader extends URLClassLoader {
	// 是否遵照雙親模式,默認雙親
	private boolean delegateLoad = true;

	private ClassLoader javaseClassLoader;

	StandJobClassLoader(boolean delegateLoad) {
		super(new URL[] {});
		this.delegateLoad = delegateLoad;
		setJavaseClassLoader();
	}

	StandJobClassLoader(ClassLoader parent, boolean delegateLoad) {
		super(new URL[] {}, parent);
		this.delegateLoad = delegateLoad;
		setJavaseClassLoader();
	}

	// 拷貝tomcat代碼
	private void setJavaseClassLoader() {

		ClassLoader j = String.class.getClassLoader();
		if (j == null) {
			j = getSystemClassLoader();
			while (j.getParent() != null) {
				j = j.getParent();
			}
		}
		this.javaseClassLoader = j;
	}

	public void addJars(File[] files) {
		if (ArrayUtils.isEmpty(files)) {
			return;
		}

		for (File file : files) {

			addJar(file);

		}
	}

	public void addJar(File file) {

		if (file != null && file.isFile() && file.getName().toLowerCase().endsWith(".jar")) {

			try {
				addURL(file.toURI().toURL());
			} catch (MalformedURLException e) {
				e.printStackTrace();
			}

		}
	}

	protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
		// 若是遵照雙親,調用原來
		if (delegateLoad) {

			return super.loadClass(name, resolve);

		}
		Class<?> clazz = null;

		synchronized (getClassLoadingLock(name)) {
			/**
			 * 判斷是否已經加載
			 */
			try {
				clazz = findLoadedClass(name);
				if (clazz != null) {
					if (resolve) {
						resolveClass(clazz);
					}
					return clazz;
				}
			} catch (Throwable e) {
			}
			/**
			 *  先有bootstrapsclassload和 extclassload加載
			 */
			try {
				clazz = javaseClassLoader.loadClass(name);
				if (clazz != null) {
					if (resolve) {
						resolveClass(clazz);
					}
					return clazz;
				}
			} catch (Throwable e) {
			}
			/**
			 * 再是最外層自定義classlaod加載
			 */
			try {
				clazz = super.findClass(name);

				if (clazz != null) {
					if (resolve) {
						resolveClass(clazz);
					}
					return clazz;
				}
			} catch (Throwable e) {
			}
			/**
			 * 最外層加載不了,調用默認後續的加載器繼續加載
			 */
			try {
				clazz = super.loadClass(name, resolve);
				if (clazz != null) {
					if (resolve) {
						resolveClass(clazz);
					}
					return clazz;
				}
			} catch (Throwable e) {
			}
			/**
			 * 加載不了跑出異常
			 */
			throw new ClassNotFoundException();
		}
	}

}

測試例子:java

測試類bootstrap

package com.stand.job.example;

public class JobServiceTest {

	public void run() {
		System.out.println("hello world" + getClass().getClassLoader().getClass());
	}

}

測試main,在當前測試項目中加入以上jar包,運行如下代碼tomcat

public static void main(String[] args) throws ClassNotFoundException, InstantiationException,
			IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		File file = new File("/Users/chichaofan/Documents/doc/workspace/example/target/");
		File[] files = file.listFiles(new FilenameFilter() {

			@Override
			public boolean accept(File dir, String name) {

				if (name.toLowerCase().endsWith(".jar")) {

					return true;
				}
				return false;

			}
		});
		for (File file2 : files) {
			StandJobClassLoader jobClassLoader = StandJobClassLoaderFactory.newInstance(false);

			jobClassLoader.addJar(file2);
			Object o = jobClassLoader.loadClass("com.stand.job.example.JobServiceTest").newInstance();
			ReflectUtils.findMethod(o.getClass(), "run").invoke(o);
		}

	}

當delegateLoad爲false時輸出ide

hello worldclass com.stand.job.common.classload.StandJobClassLoader測試

當delegateLoad爲true時輸出this

hello worldclass sun.misc.Launcher$AppClassLoaderspa

 

由此看出當delegateLoad爲false時加載器的加載順序被改變了.net

相關文章
相關標籤/搜索