JVM自定义类加载器加载指定classPath下的所有clas(2)

   翻译过来大概是:使用指定的二进制名称来加载类,这个方法的默认实现按照以下顺序查找类: 调用findLoadedClass(String)方法检查这个类是否被加载过 使用父加载器调用loadClass(String)方法,如果父加载器为Null,类加载器装载虚拟机内置的加载器调用findClass(String)方法装载类, 如果,按照以上的步骤成功的找到对应的类,并且该方法接收的resolve参数的值为true,那么就调用resolveClass(Class)方法来处理类。 ClassLoader的子类最好覆盖findClass(String)而不是这个方法。 除非被重写,这个方法默认在整个装载过程中都是同步的(线程安全的)。

   resolveClass:Class载入必须链接(link),链接指的是把单一的Class加入到有继承关系的类树中。这个方法给Classloader用来链接一个类,如果这个类已经被链接过了,那么这个方法只做一个简单的返回。否则,这个类将被按照 Java™规范中的Execution描述进行链接。

 3.2 自定义类加载器实现
    按照3.1的说明,继承ClassLoader后重写了findClass方法加载指定路径上的class。先贴上自定义类加载器。

package com.chenerzhu.learning.classloader;

import java.nio.file.Files;
import java.nio.file.Paths;

/**

@author chenerzhu

@create 2018-10-04 10:47
**/
public class MyClassLoader extends ClassLoader {
private String path;

public MyClassLoader(String path) {
this.path = path;
}

@Override
protected Class<?> findClass(String name) throws ClassNotFoundException {
try {
byte[] result = getClass(name);
if (result == null) {
throw new ClassNotFoundException();
} else {
return defineClass(name, result, 0, result.length);
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}

private byte[] getClass(String name) {
try {
return Files.readAllBytes(Paths.get(path));
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}

    

    以上就是自定义的类加载器了,实现的功能是加载指定路径的class。再看看如何使用。 

package com.chenerzhu.learning.classloader;

import org.junit.Test;

/**

Created by chenerzhu on 2018/10/4.
*/
public class MyClassLoaderTest {br/>@Test
public void testClassLoader() throws Exception {
MyClassLoader myClassLoader = new MyClassLoader("src/test/resources/bean/Hello.class");
Class clazz = myClassLoader.loadClass("com.chenerzhu.learning.classloader.bean.Hello");
Object obj = clazz.newInstance();
System.out.println(obj);
System.out.println(obj.getClass().getClassLoader());
}
}

    首先通过构造方法创建MyClassLoader对象myClassLoader,指定加载src/test/resources/bean/Hello.class路径的Hello.class(当然这里只是个例子,直接指定一个class的路径了)。然后通过myClassLoader方法loadClass加载Hello的Class对象,最后实例化对象。以下是输出结果,看得出来实例化成功了,并且类加载器使用的是MyClassLoader。

com.chenerzhu.learning.classloader.bean.Hello@2b2948e2
com.chenerzhu.learning.classloader.MyClassLoader@335eadca

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/08b465dc31dad0a31c4a44df668df91d.html