简体   繁体   English

重新加载使用自定义类加载器加载的类

[英]Reload class which is loaded using custom classloader

The following is my custom classloader class. 以下是我的自定义类加载器类。 I set this as default classloader with the following javaargs. 我使用以下javaargs将其设置为默认类加载器。

-Djava.system.class.loader=MyCustomClassLoader

import java.io.*;
public class MyCustomClassLoader extends ClassLoader { 
    public MyCustomClassLoader() { super(); } 
    public MyCustomClassLoader(ClassLoader parent) { super(parent); } 
    protected Class loadClass(String name, boolean resolve ) throws ClassNotFoundException { 
        Class c = super.loadClass(name, resolve ); 
        System.out.println( "name: " + name + ", class: " + c); 
        return c; 
    }
}

At this moment, all the classes are loaded with the above custom classloader class when I start server. 此时,当我启动服务器时,所有类都使用上面的自定义类加载器类加载。 I wish to update/reload class definition of classes that are part of a particular package (eg com.test) on demand. 我希望根据需要更新/重新加载属于特定程序包(例如com.test)的类的类定义。 How can I do it? 我该怎么做?

You should make a class loader which will load custor classes by itself, dont let super load them. 您应该创建一个类加载器,该类加载器将自己加载custor类,不要让它们超级加载。 Try my example, it may help understand 试试我的例子,可能有助于理解

package test;
import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashMap;
import java.util.Map;

class MyClassLoader extends ClassLoader {
    private Map<String, Class<?>> loadedClasses = new HashMap<>();
    private String dir;

    public MyClassLoader(String dir) throws MalformedURLException {
        this.dir = dir;
    }

    protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
        Class<?> c = findLoadedClass(name);
        if (c != null) {
            return c;
        }
        c = loadedClasses.get(name);
        if (c != null) {
            return c;
        }
        try {
            String path = dir + name.replace(".","/") + ".class";
            byte[] bytes = Files.readAllBytes(Paths.get(path)); 
            c = defineClass(name, bytes, 0, bytes.length, null);
            if (resolve) {
                resolveClass(c);
            }
            return c;
        } catch (IOException ex) {
            return super.loadClass(name, resolve);
        }
    }
}

public class ChildFirstClassLoader {

    public static void main(String[] args) throws Exception {
        ClassLoader cl1 = new MyClassLoader("target/classes/");
        Object x1 = cl1.loadClass("test.X1").newInstance();
        System.out.println(x1.getClass().getClassLoader());
        cl1 = null;

        ClassLoader cl2 = new MyClassLoader("target/classes/");
        x1 = cl2.loadClass("test.X1").newInstance();
        System.out.println(x1.getClass().getClassLoader());

    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM