2017-12-15 20 views
1

다음은 사용자 정의 클래스 로더 클래스입니다. 다음 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; 
    } 
} 

이 시점에서 서버를 시작하면 모든 클래스가 위의 사용자 정의 클래스 로더 클래스로로드됩니다. 필요에 따라 특정 패키지 (예 : com.test)의 일부인 클래스의 클래스 정의를 업데이트/새로 고침하고 싶습니다. 내가 어떻게 해?

답변

0

커스터 클래스를로드하는 클래스 로더를 만들어야합니다. 슈퍼로드 할 수는 없습니다. 이해하기 쉽도록 예제를 시도하십시오

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

이미 존재하는'URLClassLoader'보다'MyClassLoader'의 장점은 없습니다. 대답의 요점은 단일 클래스 로더 내의 클래스를 다시로드해도 작동하지 않으므로 두 개의 클래스 로더 인스턴스를 만드는 것입니다. 중복되는 클래스 로더 구현으로 관련 지점을 혼란스럽게하는 대신 집중하는 것이 좋습니다. – Holger