2011-03-16 4 views
11

: 내가 사용 할 수데이터베이스에서 java 클래스를로드하려면 어떻게해야합니까? 다음 소스 코드와 같은

package util.abc; 
public class Test{ 
    public String out(){ 
     return "Hello World!"; 
    } 
} 

:

Class c = Class.forName("util.abc.Test"); 

이 클래스를 얻을 수 있지만, 내가 원하는

클래스 경로 /util/abc/이 소스 파일 (Test.java)를 넣어하는 방법해야 데이터베이스에서이 클래스를 동적으로로드하십시오 (소스 코드를 또는 binary으로 저장하십시오)

이것은 가능합니까? 도움을

감사합니다 :)

+0

그래서 컴파일 된 클래스가 아닌 소스를 데이터베이스에 저장하고 컴파일 한 다음로드하십시오. – justkt

+0

@justkt 네, 할 수 있습니까? 감사합니다 :) – Koerr

답변

21

이미 클래스를 컴파일 가정하면, 데이터베이스에서 클래스를로드하는 DatabaseClassLoader을 만들 수 있습니다. 데이터베이스는 소스 코드가 포함되어있는 경우

public class DatabaseClassLoader extends ClassLoader { 

    public DatabaseClassLoader(ClassLoader parent, ... /* connection to database */) { 
     super(parent); 
     // store the connection 
    } 

    public Class findClass(String name) { 
     byte[] data = loadDataFromDatabase(name); 
     return defineClass(name, data, 0, data.length); 
    } 
    private byte[] loadDataFromDatabase(String name) { 
     // this is your job. 
    } 
} 

먼저 컴파일해야합니다 - 모든 파일없이이 작업을 수행하는 방법에 대한 자바 컴파일러 API로 본다.

이 방법으로로드 된 클래스는 클래스 로더가 살아있는 한 계속 살아있을 것이므로 변경 사항이 발생할 경우 클래스를 다시로드 할 수 있도록 새 클래스 로더가 필요합니다.

또한 리플렉션이 아닌 다른 방법으로 클래스와 상호 작용하려는 경우 클래스 경로에있는 인터페이스를 구현하게하고 응용 프로그램 클래스 로더가 데이터베이스의 부모가되게하는 것이 좋습니다. 클래스 로더.

아, 그리고로드하는 방법 :

Class<?> c = Class.forName("util.abc.Test", myClassLoader); 

또는 여기


직접

Class<?> c = myClassLoader.loadClass("util.abc.Test"); 
을 (사실, 어떤 인터페이스) 귀하의 인터페이스의 객체를 생성하는 방법이다 :

public <X> X getImplementingObject(Class<X> interfaceClass, String className) 
    throws ClassNotFoundException, IllegalAccessException, InstantiationException 
{ 
    ClassLoader loader = new DatabaseClassLoader(interfaceClass.getClassLoader(), ...); 
    Class<?> cl = loader.loadClass(className); 
    Class<? extends X> c = cl.asSubclass(interfaceClass); 
    return c.newInstance(); 
} 

(cl 당연히 예외를 던지지 않는 인자없는 생성자를 가지는 것 (당연히 예외가 던져 질 것이다).

이렇게하면 모든 클래스에 대해 새 ClassLoader가 만들어 지므로 인터페이스 (또는 리플렉션)를 통해서만 서로 협업 할 수 있습니다.

직접 컴파일의 경우 dcn의 대답에서 언급 한 Java 컴파일러 API를 살펴 봐야합니다. 그러나 클래스를 데이터베이스 외부로 끌어들이는 쪽보다 데이터베이스에 클래스를 넣는 편에서 컴파일하는 것이 더 나을 것이라고 생각합니다.

+0

감사합니다, 내 예를 들어, 코드 완성에 따라 수 있습니까? – Koerr

+0

@ Zenofo : 죄송합니다. 질문을 이해할 수 없습니다. 뭐하고 싶어? –

+0

나는 인터페이스를 가지고 있으며,이 인터페이스를 사용하여 많은 클래스를 구현하고 싶다. 그래서 언제든지 확장을 용이하게하기 위해, 클래스 소스를 데이터베이스에 저장하고 싶다. – Koerr

5

DB에 소스 코드를 저장하려면 Java 6 Compiler API를 사용하여 런타임에 컴파일 할 수 있습니다. 예를 들어 here을 참조하십시오.

런타임에 클래스를로드하려면 URL로 바이트 코드의 위치를 ​​지정할 수있는 경우 URLClassLoader를 사용하거나 ClassLoader.defineClass을 사용하고 바이트 코드로 바이트 코드를 제공 할 수 있습니다.

동적으로로드 된 클래스를 사용하려면 컴파일시 알려진 인터페이스를 구현해야합니다.

관련 문제