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