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

Java ClassLoader学习三:自定义ClassLoader

 
阅读更多

一.自定义ClassLoader关键

  1. 是继承ClassLoader还是继承URLClassLoader。
      1. 如果你的class文件存放于一个JAR文件里,同时你需要一些自己的load策略,可以考虑继承URLClassLoader。
      2. 如果你的class文件位于其它地方,继承ClassLoader。比喻位于普通文件夹里,可以自定义一个JyzClassLoader;如果位于网络上,可以定义一个NetworkClassLoaer,等等。
             class NetworkClassLoader extends ClassLoader {
                 String host;
                 int port;
        
                 public Class findClass(String name) {
                     byte[] b = loadClassData(name);
                     return defineClass(name, b, 0, b.length);
                 }
        
                 private byte[] loadClassData(String name) {
                     // load the class data from the connection
                      . . .
                 }
             }
  2. 重写findClass方法。

二.JyzClassLoader

 

package com.jyz.study.jdk.classLoader;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.Channels;
import java.nio.channels.FileChannel;
import java.nio.channels.WritableByteChannel;
import java.util.Arrays;

/**
 * 自定义ClassLoader
 * @author JoyoungZhang@gmail.com
 * 
 */
public class JyzClassLoader extends ClassLoader {

	private String classPath;

	public JyzClassLoader(String classPath) {
		this.classPath = classPath;
	}

	@Override
	protected Class<?> findClass(String className)
			throws ClassNotFoundException {
		byte[] bytes = loadClassData(className);
		Class<?> clazz = defineClass(className, bytes, 0, bytes.length);
		fillSigners(clazz);
		return clazz;
	}
	
	//测试ClassLoader setSigners的用法
	private void fillSigners(Class<?> clazz){
		Object[] singers = new Object[1];
		singers[0] = "JoyoungZhang@gmail.com";
		this.setSigners(clazz, singers);
	}

	private byte[] loadClassData(String className)
			throws ClassNotFoundException {
		try {
			String classFile = getClassFile(className);
			FileInputStream fis = new FileInputStream(classFile);
			FileChannel fileC = fis.getChannel();
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			WritableByteChannel outC = Channels.newChannel(baos);
			ByteBuffer buffer = ByteBuffer.allocateDirect(1024);
			while (true) {
				int i = fileC.read(buffer);
				if (i == 0 || i == -1) {
					break;
				}
				buffer.flip();
				outC.write(buffer);
				buffer.clear();
			}
			fis.close();
			return baos.toByteArray();
		} catch (IOException fnfe) {
			throw new ClassNotFoundException(className);
		}
	}

	private String getClassFile(String name) {
		StringBuffer sb = new StringBuffer(classPath);
		sb.append(File.separator).append(name.replace('.', File.separatorChar)).append(".class");
		return sb.toString();
	}

	public static void main(String[] args) {
		try {
			JyzClassLoader classLoader = new JyzClassLoader("D:\\GoogleCode\\platform-components\\trunk\\SourceCode\\component-core\\target\\classes");
			Class<?> clazz = classLoader.loadClass("com.jyz.component.core.collection.Tuple");
			
			JyzClassLoader classLoader2 = new JyzClassLoader("D:\\GoogleCode\\platform-components\\trunk\\SourceCode\\component-core\\target\\classes");
			Class<?> clazz2 = classLoader2.loadClass("com.jyz.component.core.collection.Tuple");
			
			System.out.println(clazz == clazz2);//return false
			System.out.println(clazz.equals(clazz2));//return false
			
			System.out.println("c1.getSigners is " + Arrays.toString(clazz.getSigners()));
			System.out.println(clazz.newInstance());
			System.out.println(Arrays.toString(classLoader.getPackages()));
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		} catch (InstantiationException e) {
			e.printStackTrace();
		}

	}

}



console output:
false
false
c1.getSigners is [JoyoungZhang@gmail.com]
Tuple[t1:null, t2:null]
[package java.util.jar, Java Platform API Specification, version 1.6, package java.nio.channels, Java Platform API Specification, version 1.6, package java.util, Java Platform API Specification, version 1.6, package sun.util, Java Platform API Specification, version 1.6, package java.net, Java Platform API Specification, version 1.6, package sun.reflect.misc, Java Platform API Specification, version 1.6, package sun.security.provider, Java Platform API Specification, version 1.6, package sun.net.www.protocol.jar, Java Platform API Specification, version 1.6, package sun.security.action, Java Platform API Specification, version 1.6, package java.nio.charset, Java Platform API Specification, version 1.6, package sun.io, Java Platform API Specification, version 1.6, package java.io, Java Platform API Specification, version 1.6, package sun.nio, Java Platform API Specification, version 1.6, package sun.net.www, Java Platform API Specification, version 1.6, package java.util.zip, Java Platform API Specification, version 1.6, package java.lang.ref, Java Platform API Specification, version 1.6, package java.lang, Java Platform API Specification, version 1.6, package sun.misc, Java Platform API Specification, version 1.6, package sun.net.www.protocol.file, Java Platform API Specification, version 1.6, package java.util.concurrent, Java Platform API Specification, version 1.6, package java.util.concurrent.atomic, Java Platform API Specification, version 1.6, package java.nio.charset.spi, Java Platform API Specification, version 1.6, package java.nio.channels.spi, Java Platform API Specification, version 1.6, package java.nio, Java Platform API Specification, version 1.6, package java.util.concurrent.locks, Java Platform API Specification, version 1.6, package java.security, Java Platform API Specification, version 1.6, package sun.reflect, Java Platform API Specification, version 1.6, package java.lang.reflect, Java Platform API Specification, version 1.6, package sun.nio.cs, Java Platform API Specification, version 1.6, package sun.security.util, Java Platform API Specification, version 1.6, package sun.nio.cs.ext, package com.jyz.study.jdk.classLoader, package java.security.cert, Java Platform API Specification, version 1.6, package sun.nio.ch, Java Platform API Specification, version 1.6, package sun.net.util, Java Platform API Specification, version 1.6, package sun.jkernel, Java Platform API Specification, version 1.6]

 

三.再来说说laodClass

      http://zy19982004.iteye.com/blog/1983240里文字解释了一下loadClass的过程。下面debug一下。

      进入点Class<?> clazz = classLoader.loadClass("com.jyz.component.core.collection.Tuple");

  1. JyzClassLoader委派给AppClassLoader,AppClassLoader委派给ExtClassLoader,ExtClassLoader委派给BootstrapLoader,BootstrapLoader找不到,ExtClassLoader自己去找。想想为什么JyzClassLoader会委派给AppClassLoader?参考http://zy19982004.iteye.com/blog/1983240。
  2. ExtClassLoader找不到,AppClassLoader自己去找。
  3. AppClassLoader找不到J,yzClassLoader自己去找。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics