如何从数据库加载java类?

喜欢以下源代码:

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

我可以用:

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

获取此类,但我必须将此源文件( Test.java )放在ClassPath /util/abc/

我想从数据库动态加载这个类(将源代码存储为stringbinary

这个有可能 ?

感谢帮助 :)

假设您已经编译了该类,您可以创建一个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. } } 

如果数据库只包含源代码,则必须先编译它 – 查看Java编译器API,了解如何在没有任何文件的情况下执行此操作。

请注意,只要类加载器处于活动状态,以这种方式加载的类将保持活动状态,因此您需要一个新的类加载器才能在发生更改时重新加载该类。

此外,如果您希望通过除reflection之外的其他方式与类进行交互,则最好让它实现一些接口(它本身位于类路径中),并让应用程序类加载器成为数据库类加载器的父级。

啊,以及如何加载:

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

或直接

 Class c = myClassLoader.loadClass("util.abc.Test"); 

这是一个创建接口对象(实际上是任何接口)的方法:

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

(它需要类有一个无参数的构造函数,当然不会抛出任何exception(如果有的话,你也会抛出这个exception)。

这为每个这样的类创建了一个新的ClassLoader,因此它们只能通过接口(或reflection)相互协作。

对于即时编译,您应该查看Java编译器API,如dcn的答案中所述 。 但是我认为最好将编译放在数据库中,而不是把它们拉出来。

如果要将源代码存储在DB中,可以使用Java 6 Compiler API在运行时编译它。 请看这里的例子。

为了在运行时加载类,如果可以使用URL指定字节码的位置,则可以使用URLClassLoader,也可以使用ClassLoader.defineClass并将字节码作为字节数组提供。

无论哪种方式,您都应该注意,为了使用动态加载的类,它应该实现在编译时已知的接口。