自定义classloader主要实现的方法是 findClass(String name) , 而我们调用的则是loadClass来加载类

具体的loadClass代码请自己查阅,直接上干货:

public class NorClassLoader extends ClassLoader{
	URL[] urls = null;
	public NorClassLoader(){
		super();
	}
	public NorClassLoader(URL[] urls){
		this.urls = urls;
	}
	public NorClassLoader(URL[] urls,ClassLoader parent){
		super(parent);
		this.urls = urls;
	}
	@Override
	protected Class<?> findClass(String name) throws ClassNotFoundException {
		Class<?> clazz = null;
		if(name == null || name.length()==0) 
			throw new ClassNotFoundException("class <"+name+"> can't found");
		try{
			byte[] buffer = searchResource(name);
			if(buffer == null){
				throw new ClassNotFoundException("class <"+name+"> can't found");
			}
			clazz = defineClass(null, buffer, 0, buffer.length);
		}catch(Exception e){
			throw new ClassNotFoundException("class <"+name+"> can't found",e);
		}
		if(clazz == null){
			throw new ClassNotFoundException("class <"+name+"> can't found");
		}
		return clazz;
	}
	private byte[] searchResource(String name) throws IOException{
		if(urls == null || urls.length ==0){
			throw new NullPointerException("urls can't be null or empty");
		}
		String pathName = name.replaceAll("\\.", "/");
		ByteArrayOutputStream baos = null;
		for(URL url : urls){
			try {
				File file = new File(url.toURI());
				if(file.exists() && file.isDirectory()){// source folder
					File clazzFile = new File(file,pathName+".class");
					if(clazzFile.exists() && clazzFile.isFile()){
						baos = new ByteArrayOutputStream();
						FileInputStream fis = new FileInputStream(clazzFile);
						int b = 0;
						while((b=fis.read()) >=0){
							baos.write(b);
						}
						fis.close();
						break;
					}
				}else{
					if(file.getName().endsWith(".jar")){// jar file
						JarFile jarFile = new JarFile(new File(url.toURI()));
						ZipEntry zentry = jarFile.getEntry(pathName+".class");
						if(zentry ==null){
							continue;
						}else{
							InputStream is = jarFile.getInputStream(zentry);
							baos = new ByteArrayOutputStream();
							int b = 0;
							while((b=is.read())>=0){
								baos.write(b);
							}
							is.close();
							jarFile.close();
							break;
						}
					}else if(file.getName().endsWith(".zip")){// zip file
						ZipFile zipFile = new ZipFile(new File(url.toURI()));
						ZipEntry zentry = zipFile.getEntry(pathName);
						if(zentry ==null){
							continue;
						}else{
							InputStream is = zipFile.getInputStream(zentry);
							baos = new ByteArrayOutputStream();
							int b = 0;
							while((b=is.read())>=0){
								baos.write(b);
							}
							is.close();
							zipFile.close();
							break;
						}
					}else{ // can't process the file type
						continue;
					}
				}
			} catch (URISyntaxException e) {
				continue;
			}
		}
		return baos ==null ? null : baos.toByteArray();
	}

再来一个 测试用例,用例是从其他项目即时编译一个源文件用classloader加载

public class TestClassloader {
	@Before
	public void setUp(){
		String[] args = new String[]{"-extdirs","/home/tt/workspace/java/nor/deps/",
				"-sourcepath","/home/tt/workspace/java/nor/src/",
				"-6","-d","/home/tt/workspace/java/nor/testbin/",
				"/home/tt/workspace/java/nor/src/org/nutz/template/Start.java"};
		new org.eclipse.jdt.internal.compiler.batch.Main(new PrintWriter(new ByteArrayOutputStream()),new PrintWriter(new ByteArrayOutputStream()),false,null,null).compile(args);
	}
	@Test
	public void testNorClassloader() throws ClassNotFoundException, MalformedURLException{
		ClassLoader cl = new NorClassLoader(new URL[]{new File("/home/tt/workspace/java/nor/testbin/").toURI().toURL(),
				new File("/home/tt/workspace/java/nor/deps/jetty-xml-7.2.2.v20101205.jar").toURI().toURL()
		},Thread.currentThread().getContextClassLoader());
		Class<?> clazz = cl.loadClass("org.nutz.template.Start");
		Assert.assertEquals("org.nutz.template.Start", clazz.getName());
		clazz = cl.loadClass("org.eclipse.jetty.xml.XmlParser");
		Assert.assertEquals("org.eclipse.jetty.xml.XmlParser", clazz.getName());
	}
	@After
	public void tearDown(){
		Files.deleteDir(new File("/home/tt/workspace/java/nor/testbin/"));
	}
}

大家把 其中的变量适当替换一下,如果有class文件可以直接用classloader进行加载,