如何从数据库加载java类? [英] How can I load java class from database?

查看:154
本文介绍了如何从数据库加载java类?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如下面的源代码:

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

我可以使用:

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

获取此类,但我必须放入此源文件( Test ClassPath中的.java / util / abc /

to get this Class,but I must to put this source file(Test.java) in ClassPath /util/abc/

我希望动态加载这个数据库中的类(将源代码存储为 string binary

I want dynamic load this class from database (store the source code as string,or binary)

这可能吗?

感谢您的帮助:)

推荐答案

假设您已经编译了该类,您可以创建一个 DatabaseClassLoader ,它从数据库加载该类。

Assuming you already compiled the class, you can create a DatabaseClassLoader, which loads the class from a database.

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,了解如何在没有任何文件的情况下执行此操作。

If the database only contains the source code, you'll have to compile it first - look into the Java compiler API for how to do this without any files.

注意,以这种方式加载的类将保持活动状态因为类加载器是活的,所以你需要一个新的类加载器,以便在发生更改时重新加载类。

Pay attention, the class loaded this way will stay alive as long as the classloader is alive, so you'll need a new class loader to be able to reload the class in case of changes.

此外,如果你想与之交互除了反射之外的其他方式,你最好让它实现一些接口(它本身就在你的类路径中),并让应用程序类加载器成为你的数据库类加载器的父类。

Also, if you want to interact with the class by other ways than reflection, you would better let it implement some interface (which itself is in your class path), and let the application class loader be the parent of your database class loader.

啊,以及如何加载:

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

或直接

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






这是一种创建界面对象的方法(实际上是任何界面):


Here is a method which creates objects of your interface (of any interface, in fact):

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

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

(It needs the class to have a no-argument constructor which does not throw any exceptions, of course (if it does, you'll get this exception thrown, too).

这会为每个这样的类创建一个新的ClassLoader,所以它们只能通过接口(或反射)相互合作。

This creates a new ClassLoader for every such class, so they can only cooperate with each other by means of the interface (or reflection).

对于动态编译,您应该查看Java Compiler API,如答案中所述来自 dcn 。但是我认为最好将这些类放入数据库进行编译,而不是将它们拉出来的那一方。

For on-the-fly compiling you should look at the Java Compiler API, as mentioned in the answer from dcn. But I think it would be better to do the compiling on the side which puts the classes into the database than the side who pulls them out.

这篇关于如何从数据库加载java类?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆