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

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自己去找。
分享到:
评论

相关推荐

    Java ClassLoader定制实例

    在某些特定场景下,比如动态加载代码、插件系统或者安全隔离等,我们需要自定义ClassLoader来实现特定的加载逻辑。例如,我们可能希望加载网络上的类,或者从数据库中读取类的字节码。 以...

    Java ClassLoader学习总结

    * 有三种类型的 ClassLoader:bootstrap classloader、ExtClassLoader 和 AppClassLoader。 * bootstrap classloader 负责加载 Java 核心的 API,ExtClassLoader 负责加载 Java 的扩展 API,而 AppClassLoader 负责...

    Understanding the Java ClassLoader

    #### 三、自定义ClassLoader实践 为了更深入地理解ClassLoader的工作机制,我们将构建一个简单的自定义ClassLoader示例,该ClassLoader能够在加载之前自动编译代码。 **1. 自定义ClassLoader的基本步骤** - **...

    Java ClassLoader原理

    ### Java ClassLoader原理详解 #### 摘要 本文探讨了Java虚拟机(JVM)中的一个重要特性:动态类加载(Dynamic Class Loading)。这一机制为Java平台提供了强大的能力,允许在运行时安装软件组件,例如从网络下载...

    java classloader

    在Java中,用户可以通过自定义ClassLoader来实现特定的加载逻辑,比如从数据库或网络中加载类。这使得Java可以支持许多高级功能,例如插件系统、热部署和模块化系统(如Java 9的Jigsaw项目)。 `JAVA2深度历险.jpg`...

    java classloader讲义-淘宝网

    通过对Java ClassLoader的深入了解,我们可以更好地理解Java类的加载机制以及如何通过自定义ClassLoader来满足特定的应用需求。淘宝网的成功实践为我们提供了宝贵的参考案例,展示了ClassLoaders在实际项目中的重要...

    Java ClassLoader Tutorial.zip

    1. 继承ClassLoader:开发者可以通过继承`java.lang.ClassLoader`并重写`loadClass()`方法来自定义类加载逻辑。 2. 加载自定义位置的类:自定义ClassLoader可以加载非标准路径的类,如从网络、数据库或其他存储介质...

    理解Java ClassLoader机制

    自定义ClassLoader需要继承`java.lang.ClassLoader`类,并重写`findClass()`或`loadClass()`方法。通过这两个方法,你可以控制类的加载来源和方式。 在实际开发中,理解ClassLoader机制可以帮助解决一些问题,例如...

    自定义classloader的使用

    创建自定义Classloader需要继承java.lang.ClassLoader类,并重写其关键方法,如`findClass(String name)`或`loadClass(String name)`。这两个方法分别用于查找指定类的字节码和实际加载类。在`findClass`中,我们...

    java ClassLoader机制及其在OSGi中的应用

    Java提供了三种内置的ClassLoader: 1. BootstrapClassLoader(启动类加载器):它是JVM的基础,由C++实现,不继承自`java.lang.ClassLoader`。BootstrapClassLoader负责加载JVM的核心类库,包括rt.jar、charsets....

    测试普通Java程序ClassLoader等级关系的Demo程序

    4. **自定义ClassLoader**:开发者可以创建自己的ClassLoader子类,用于特定的需求,如从网络、数据库或特定目录加载类。 在"Test"这个Demo程序中,可能包含了几种测试用例,用于演示不同ClassLoader如何加载类,...

    Java SE: ClassLoader in depth

    在Java中,有几种不同类型的ClassLoader: - 启动类加载器(Bootstrap ClassLoader):负责加载JAVA_HOME/lib目录下的,或被-Xbootclasspath参数指定路径中的,并且是虚拟机识别的类库到JVM中。 - 扩展类加载器...

    java自定义类加载classloader文档,包括代码

    通过本文的学习,我们不仅深入了解了Java类加载器的工作原理,还通过具体的自定义类加载器实例掌握了如何在实践中应用这些理论知识。类加载器在Java开发中扮演着极其重要的角色,尤其是在需要实现动态加载类的应用...

    classloader

    3. 整合自定义ClassLoader:了解如何将自定义的ClassLoader集成到Java应用程序中,替换或扩展默认的加载行为。 4. 考虑Java 2版本的兼容性:学习如何修改你的ClassLoader以适应Java 2及以上版本的特性,比如支持...

    JAVA ClassLoader 讲解 (类加载器)

    * 学习如何将自定义类加载器集成到Java应用中。 * 修改类加载器以适应Java 2版本。 为了更好地理解本教程,你需要具备以下基础: * 基本的Java编程能力,包括能够创建、编译和执行简单的命令行Java程序。 * 对类...

    java6.0源码-HikariCP:自定义版本的HikariCP支持ClassLoader隔离

    java6.0源码 ![]() HikariCP更快。 Hi·ka·ri [hi·ka·'lē] (*来源:日本*):光; 射线。 [![构建状态]() [![问题统计]() [![问题统计]() [![覆盖状态]() [![依赖状态]() 快速、简单、可靠。 HikariCP 是一个“零...

    ClassLoader

    ### Java虚拟机中ClassLoader概述与双亲委托机制详解 #### 一、ClassLoader概念与作用 在Java编程语言中,`ClassLoader`是一个非常重要的组件,它负责加载程序运行所需的类文件到Java虚拟机(JVM)中。`ClassLoader`...

Global site tag (gtag.js) - Google Analytics