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
- SpEL Spring Expression Language, @Value和@Cache等注解都是基于SpEL实现的, 可以参考使用demo文章