我曾经见过一个“规则引擎”,是在应用系统web界面直接编写java代码,然后保存后,规则即生效,我一直很是奇怪,这是如何实现的呢?实际这就好像jsp,被中间件动态的编译成java文件,有被动态的编译成class,同时又动态的加载到classloader中。所以,本质上,纯java得规则引擎,是100%可以实现的。
1、动态生成java源代码。这个过程太过简单,直接略过。
2、动态编译。
我看我们自己的规则引擎也有动态编译,就是在生成BOM模型的时候。但是是调用Process执行javac。但这种方式坦白来说不好。因为javac,的命令参数写法和操作系统有关,也就是windows和linux的写法有少量不同。后来发现jdk提供一个动态编译的类。
JavaCompiler javac;
javac = ToolProvider.getSystemJavaCompiler();
int compilationResult = javac.run(null,null,null, "-g","-verbose",javaFile);
这样就可以动态进行编译。前两个参数是输入参数、输出参数,我觉得没有什么用,第三个参数是编译输出信息,默认输出到System.out.err里面。从第四个参数开始,就是javac的参数,可以用数组,也可以直接逗号分割。
3、动态加载。
动态加载实际就是调用ClassLoader。当然需要反射机制调用其中的一个内部分方法,使之变成外部可调用的方法。
File file = new File("/Users/yangming/Work/DevWorkSpace/ssac/gx_hx/test/"); URLClassLoader classloader = (URLClassLoader) ClassLoader.getSystemClassLoader();
Method add = URLClassLoader.class.getDeclaredMethod("addURL", new Class[]{URL.class});
add.setAccessible(true);
add.invoke(classloader, new Object[]{file.toURI().toURL()});
Class c = classloader.loadClass("Test");
Object o = c.newInstance();
Method m = c.getDeclaredMethod("getString");
m.invoke(o, null);
这样就完成了类的动态加载。