牛逼,Java中表达式引擎工具就用它!建议收藏,一定用的到!!
最近在負責一個和定價有關的系統,要做分層的價格決策。在決策過程中有兩個訴求:
1、需要根據一定的表達式公式,進行分層決策。如訂單金額大于1000元時,給10塊錢紅包,介于100和1000之間的給5元紅包。
2、具體價格的產出,需要根據一定的公式。比如根據用戶訂單金額,乘一個固定的系數。
這時候,就需要一個表達式引擎。需要能夠做表達式匹配和數學公式計算。
調研了業內很多的表達式引擎工具,如Ognl、MVEL、IKExpression、Aviator等,根據易用性、性能、可維護性、功能多少等,最終選擇了Aviator這款工具。
Aviator
根據Aviator文檔的介紹,Aviator 的基本過程是將表達式直接翻譯成對應的 java 字節碼執行,除了依賴 commons-beanutils 這個庫之外(用于做反射)不依賴任何第三方庫,因此整體非常輕量級,整個 jar 包大小哪怕發展到現在 5.0 這個大版本,也才 430K。
同時, Aviator 內置的函數庫非常“節制”,除了必須的字符串處理、數學函數和集合處理之外,類似文件 IO、網絡等等你都是沒法使用的,這樣能保證運行期的安全,如果你需要這些高階能力,可以通過開放的自定義函數來接入。因此總結它的特點是:
? 高性能
? 輕量級
? 一些比較有特色的特點:
? 支持運算符重載
? 原生支持大整數和 BigDecimal 類型及運算,并且通過運算符重載和一般數字類型保持一致的運算方式。
? 原生支持正則表達式類型及匹配運算符 =~
? 類 clojure 的 seq 庫及 lambda 支持,可以靈活地處理各種集合
? 開放能力:包括自定義函數接入以及各種定制選項
用法
Aviator 用法很簡簡單,首先引入jar包:
<dependency><groupId>com.googlecode.aviator</groupId><artifactId>aviator</artifactId><version>5.2.1</version> </dependency>獲取一個Aviator實例:
AviatorEvaluatorInstance aviatorEvaluator = AviatorEvaluator.getInstance()接著,對表達式進行編譯:
Expression expression = aviatorEvaluator.compile("a > 100 && b< 100"); Expression expression = aviatorEvaluator.compile("a + 150");在執行表達式驗證和計算。
expression..execute(params);這里面對params是一個Map,Map中的Key就是表達式中的變量,如a、b等。
如:
AviatorEvaluator.getInstance().compile("a > 300 && a<500").execute(ImmutableMap.of("a", new BigDecimal(400)); AviatorEvaluator.getInstance().compile("a + 123.2").execute(ImmutableMap.of("a", 400)).compareTo(new BigDecimal("523.2"));為了方便使用,我們還可以定一個util工具類:
/*** 表達式處理工具類** @author Hollis*/ public class ExpressionUtil {public static AviatorEvaluatorInstance aviatorEvaluator = AviatorEvaluator.getInstance();static {aviatorEvaluator.setOption(Options.ALWAYS_PARSE_FLOATING_POINT_NUMBER_INTO_DECIMAL, true);}/***表達式驗證**/public static boolean verify(String expression, Map<String, Object> params) {return (Boolean)aviatorEvaluator.compile(expression).execute(params);}/*** 表達式計算* @param expression 表達式* @param params 需要替換的表達式參數* @return calculate result*/public static BigDecimal calculate(String expression, Map<String, Object> params) {return (BigDecimal)aviatorEvaluator.compile(expression).execute(params);} }使用單元測試對以上方法進行驗證:
public class ExpressionUtilTest {@Testpublic void test() {Assert.assertTrue(ExpressionUtil.verify("a > 300 && a<500", ImmutableMap.of("a", new BigDecimal(400))));Assert.assertFalse(ExpressionUtil.verify("a > 300 && a<500", ImmutableMap.of("a", new BigDecimal(600))));Assert.assertTrue(ExpressionUtil.verify("a > 300 && b<500 && c < 600",ImmutableMap.of("a", new BigDecimal(400), "b", new BigDecimal(400), "c", new BigDecimal(500))));Assert.assertFalse(ExpressionUtil.verify("a > 300 && b<500 && c < 600",ImmutableMap.of("a", new BigDecimal(400), "b", new BigDecimal(400), "c", new BigDecimal(700))));}@Testpublic void test1() {Assert.assertEquals(0,ExpressionUtil.calculate("a + 123.2", ImmutableMap.of("a", 400)).compareTo(new BigDecimal("523.2")));Assert.assertEquals(0,ExpressionUtil.calculate("a + b", ImmutableMap.of("a", new BigDecimal("0.1"), "b", new BigDecimal("0.2"))).compareTo(new BigDecimal("0.3")), 0);}}以上,就是簡單的Aviator的使用方法,快快在你的代碼中實踐起來吧,如果有收獲,請一鍵三連哦!!!
總結
以上是生活随笔為你收集整理的牛逼,Java中表达式引擎工具就用它!建议收藏,一定用的到!!的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: mapReducer第一个例子WordC
- 下一篇: js 实时输入事件