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