我曾經見過一個“規則引擎”,是在應用系統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);
這樣就完成了類的動態加載。