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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章