使用表达式代替ifelse实现复杂策略,类似于策略模式
另外判断逻辑可以放到运营后台进行配置
核心方法 com.googlecode.aviator.AviatorEvaluator.execute
表达式判断的时候,如果靠左边的条件可以拿到判定结果,右边就不用判断了,如果后面是方法的话,就不会调用了,减少了不必要的方法调用
package com.demo.aviator;
import com.google.common.collect.ImmutableMap;
import com.googlecode.aviator.AviatorEvaluator;
import com.googlecode.aviator.runtime.function.AbstractVariadicFunction;
import com.googlecode.aviator.runtime.type.AviatorLong;
import com.googlecode.aviator.runtime.type.AviatorObject;
import com.googlecode.aviator.runtime.type.AviatorType;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
@Slf4j
public class AviatorEvaluatorTest {
// 简单的例子
@Test
public void executeSimple() throws Exception {
// 表达式expression判断参数env的属性age是否大于1,结果为true
final String expression = "age > 1";
final ImmutableMap<String, Object> env = ImmutableMap.of("age", 10);
final Object result = AviatorEvaluator.execute(expression, env);
System.out.println(result);
}
// 自定义的复杂场景
@Test
public void execute() throws Exception {
// 构建参数
final Foo foo = Foo.builder().age(18).richer(true).orderNo("Od0001").productNo("prd01001").gender(0).build();
// 将参数放到map中
Map<String, Object> param = new HashMap<>();
param.put("p", foo);
// 增加自定义方法
AviatorEvaluator.addFunction(new MyAviatorFunction());
// 表达式,除了判断参数中的属性,还会调用方法进行判断
final String expression = "p.age > 16 && p.richer && p.gender == 0 && myFun() == 1 && myFun(p) == 1";
final Object result = AviatorEvaluator.execute(expression, param);
// 输出判断结果
System.out.printf("result=%s expression=%s param=%s %n", result, expression, param);
}
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
// 自定义入参
public static class Foo {
private String productNo;
private String orderNo;
private int gender;
private boolean richer;
private int age;
}
// 自定义获取数据的方法
static class MyAviatorFunction extends AbstractVariadicFunction {
// 自定义方法名称
@Override
public String getName() {
return "myFun";
}
@Override
public AviatorObject call(Map<String, Object> env) {
log.info("------- {}", env);
return new AviatorLong(1);
}
@Override
public AviatorObject variadicCall(Map<String, Object> env, AviatorObject... args) {
final AviatorObject arg1 = args[0];
final Foo foo = (Foo) arg1.getValue(env);
log.info("------- env={} foo={}", env, foo);
final AviatorType type = arg1.getAviatorType();
return new AviatorLong(1);
}
}
}