介紹
QLExpress腳本引擎
1、線程安全,引擎運算過程中的產生的臨時變量都是threadlocal類型。
2、高效執行,比較耗時的腳本編譯過程可以緩存在本地機器,運行時的臨時變量創建采用了緩沖池的技術,和groovy性能相當。
3、弱類型腳本語言,和groovy,javascript語法類似,雖然比強類型腳本語言要慢一些,但是使業務的靈活度大大增強。
4、安全控制,可以通過設置相關運行參數,預防死循環、高危系統api調用等情況。
5、代碼精簡,依賴最小,250k的jar包適合所有java的運行環境,在android系統的低端pos機也得到廣泛運用。
引入
<dependency><groupId>com.alibaba</groupId><artifactId>QLExpress</artifactId><version>3.3.1</version>
</dependency>
案例
簡單表達式
public static void testSimple() throws Exception {ExpressRunner runner = new ExpressRunner();IExpressContext<String, Object> context = new DefaultContext<String, Object>();// 設置變量context.put("a", 0);context.put("b", 20);// 定義QLExpress表達式String expression = "a == 0";// 執行表達式Object result = runner.execute(expression, context, null, true, false);// 輸出結果System.out.println("Result: " + result);}
動態表達式
public static void testDyExpress() throws Exception {ExpressRunner runner = new ExpressRunner();IExpressContext<String, Object> context = new DefaultContext<String, Object>();// 設置變量context.put("a", 10);context.put("b", 20);// 定義表達式String expression = "a + b * x";// 設置動態變量context.put("x", 2);long s = System.currentTimeMillis();// 執行表達式Object result = runner.execute(expression, context, null, false, false);// 輸出結果System.out.println("Result: " + result + "time " + (System.currentTimeMillis() - s));}
自定義方法
自己集成Operator 實現AverageOperator
public class AverageOperator extends Operator {public AverageOperator(String name) {this.name = name;}@Overridepublic Object executeInner(Object[] list) throws Exception {// 獲取傳遞給自定義方法的參數列表double num1 = Double.parseDouble(list[0].toString());double num2 = Double.parseDouble(list[1].toString());// 計算平均值double average = (num1 + num2) / 2;// 返回結果return average;}
}
public static void testCustomMethod() throws Exception {ExpressRunner runner = new ExpressRunner();IExpressContext<String, Object> context = new DefaultContext<String, Object>();// 設置變量context.put("a", 10);context.put("b", 20);// 定義表達式String expression = "average(a, b)";// 注冊自定義方法runner.addFunction("average", new AverageOperator("average"));// 執行表達式Object result = runner.execute(expression, context, null, false, false);// 輸出結果System.out.println("Result: " + result);}
自動義規則
同自定義方法實現
class IsAdultOperator extends Operator {public IsAdultOperator(String name) {this.name = name;}@Overridepublic Object executeInner(Object[] list) throws Exception {int age = Integer.parseInt(list[0].toString());return age >= 18;
public static void testCustomRule() throws Exception {// 創建ExpressRunner實例ExpressRunner runner = new ExpressRunner();// 注冊自定義方法runner.addFunction("isAdult", new IsAdultOperator("isAdult"));// 創建規則String rule = "if isAdult(age) then result = '成年人'; else result = '未成年人'; end";// 創建上下文IExpressContext<String, Object> context = new DefaultContext<>();context.put("age", 18);// 執行規則runner.execute(rule, context, null, true, false);// 獲取結果Object result = context.get("result");// 輸出結果System.out.println("Result: " + result);}
執行結果
參考
QLExpress