java腳本表達式

java中的表達式有很多種,挑花眼睛,直接推薦使用QLExpress和Groovy

  • QLExpress 被廣泛應用在阿里的電商業務場景 ,速度較快, 擴展非常靈活,性能和Groovy相當。
    可以自定義Operator來加強操作符的功能,例如我自定義了一個MyOperatorEqualsLessMore來加強OperatorEqualsLessMore的功能,實現了自定義對象的比較
runner.replaceOperator("==",new MyOperatorEqualsLessMore("=="));
runner.execute("mytree==1", expressContext, null, false, false);
runner.execute("mytree=='1'", expressContext, null, false, false);
public class MyOperatorEqualsLessMore extends Operator {
    public MyOperatorEqualsLessMore(String opStr) {
        this.name = opStr;
    }
    @Override
    public Object executeInner(Object[] objects) throws Exception {
    // 擴展以後這裏可以實現MyTree對象的比較操作
        if(objects[0] instanceof MyTree){
            String opStr = this.name;
            int i =  Operator.compareData(objects[1] instanceof CharSequence || objects[1] instanceof Character? objects[0].toString() : NumberUtils.toInt(objects[0].toString()), objects[1]);
            boolean result = false;
            if (i > 0) {
                if (!opStr.equals(">") && !opStr.equals(">=") && !opStr.equals("!=") && !opStr.equals("<>")) {
                    result = false;
                } else {
                    result = true;
                }
            } else if (i == 0) {
                if (!opStr.equals("=") && !opStr.equals("==") && !opStr.equals(">=") && !opStr.equals("<=")) {
                    result = false;
                } else {
                    result = true;
                }
            } else if (i < 0) {
                if (!opStr.equals("<") && !opStr.equals("<=") && !opStr.equals("!=") && !opStr.equals("<>")) {
                    result = false;
                } else {
                    result = true;
                }
            }

            return result;
        }
        return OperatorEqualsLessMore.executeInner(this.name, objects[0], objects[1]);
    }
}
  • Groovy 支持豐富的語法糖,集成簡單,速度較快,當前項目正在使用的就是Groovy,(1..100).each{println(it)}自定義連續數組以及each遍歷非常好用
    支持運算符重載,各種運算符被映射到普通的java對象的方法調用,完整的操作符參照文章groovy–運算符重載,例如,
class Basic{
    int value;
    // +
    Basic plus(Basic that){
        return new Basic(value: this.value+that.value)
    }
    // *
    Basic multiply(Basic that){
        return new Basic(value: this.value*that.value)
    }
    // TODO to be fullfilled
}

對象比較只需要在對象中重寫equals和compareTo方法即可,比QLExpress更加靈活

Operator Method
a == b a.equals(b) or a.compareTo(b) == 0 **
a != b ! a.equals(b)
a <=> b a.compareTo(b)
a > b a.compareTo(b) > 0
a >= b a.compareTo(b) >= 0
a < b a.compareTo(b) < 0
a <= b a.compareTo(b) <= 0
  • Drools, 可以將自定義的規則打成jar包,利用內置maven動態監控maven倉庫的jar包變化,實現規則動態替換
  • fel 通常情況下,Fel-0.7每秒可以執行千萬次表達式(不包含編譯時間)。速度是Jexl-2.0的20倍以上。目前還沒有發現開源的表達式引擎比Fel快。這是一個非常追求極致效率的作品,它能識別重複變量,開提供function註冊、SourceBuilder等編譯後期優化,基本可以保持到和java源碼靜態編譯後只低一個數量級的效率。
    靜態類型,不支持多行表達式,new對象等,2013-3-26後停止更新
  • radar 實時風控引擎(Risk Engine),自定義規則引擎(Rule Script),完美支持中文,適用於反欺詐(Anti-fraud)應用場景,有圖形界面配置規則
  • Aviator 輕量級和高性能,介於Groovy這樣的重量級腳本語言和IKExpression這樣的輕量級表達式引擎之間
  • JSEL 性能較好
  • MVEL
  • IKExpression , 公司過去使用IK,在執行大量表達式的時候速度會超級慢,後面改用Groovy
  • Esper
  • BeanShell
  • EL
  • jep
  • JavaCC
  • JEval
  • JEXL
  • JParsec
  • JXPath
  • rhino
  • SimpleEL
  • Spads
  • expression-analyzer
  • Ognl 速度非常慢 ,jsp頁面標籤代碼,arthas使用的也是ongl語法
  • janino
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章