2017-12-15 5 views
1

Das folgende ist meine benutzerdefinierte Classloader-Klasse. Ich habe dies als Standard Classloader mit den folgenden Javaargs festgelegt.Reload-Klasse, die mit benutzerdefinierten Classloader geladen wird

In diesem Moment werden alle Klassen mit der oben genannten benutzerdefinierten Classloader-Klasse geladen, wenn ich den Server starte. Ich möchte die Klassendefinition von Klassen, die Teil eines bestimmten Pakets (z. B. com.test) sind, bei Bedarf aktualisieren/neu laden. Wie kann ich es tun?

Antwort

0

Sie sollten einen Klassenlader machen, der die custor-Klassen selbst lädt, lassen Sie sie nicht super laden. Versuchen Sie mein Beispiel, es kann helfen zu verstehen

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()); 

    } 
} 
+0

Es gibt keinen Vorteil von 'MyClassLoader' gegenüber dem bereits vorhandenen 'URLClassLoader'. Der entscheidende Punkt Ihrer Antwort ist, dass Sie zwei Klassenlader-Instanzen erstellen, da das erneute Laden von Klassen innerhalb eines einzelnen Klassenladeprogramms nicht funktioniert. Ich empfehle, sich darauf zu konzentrieren, anstatt mit einer redundanten Klassenladerimplementierung von dem relevanten Punkt abzulenken. – Holger

Verwandte Themen