【脚本】JAVA 执行 阿里QLExpress 脚本 demo 进阶版
测试demo
import com.ql.util.express.DefaultContext;
public class QlExpressTest {
public static void main(String[] args) throws Exception {
QLExpressManager qlExpressManager = new QLExpressManager();
DefaultContext<String, Object> context = new DefaultContext<>();
//阈值1000
context.put("threshold", 1000);
context.put("name", "orderMoney");
context.put("channelType", "mobile");
context.put("type", 1);
String qlExpress = " 1>0?1:0 ";
Object result = qlExpressManager.execute(qlExpress, context);
System.out.println(result);
}
}实际用法
@Resource
private QLExpressManager qlExpressManager;
String 脚本 = " 1 + 1"
Object execute = qlExpressManager.execute(脚本, dataMap);package com.common.qlexpress;
import java.math.BigDecimal;
/**
* 规则处理器接口
*
*/
public interface AbstractRuleHandler extends RuleHandler {
/**
* 根据渠道创意查询
*/
BigDecimal doHandler(Integer type, String channelType);
}import org.springframework.stereotype.Component;
import java.math.BigDecimal;
@Component
public class OrderMoneyHandler implements AbstractRuleHandler {
@Override
@QlRule(methodName = "doHandler", desc = "订单金额统计查询")
public BigDecimal doHandler(Integer type, String channelType) {
return null;
}
}import com.ql.util.express.IExpressContext;
import org.springframework.context.ApplicationContext;
import java.util.HashMap;
import java.util.Map;
/**
* QLExpress 上下文定义类
*
*/
public class QLExpressContext extends HashMap<String, Object> implements IExpressContext<String, Object> {
private ApplicationContext applicationContext;
public QLExpressContext(Map<String, Object> properties, ApplicationContext context) {
super(properties);
this.applicationContext = context;
}
@Override
public Object get(Object name) {
Object result;
result = super.get(name);
try {
if (result == null && this.applicationContext != null && this.applicationContext.containsBean((String) name)) {
result = this.applicationContext.getBean((String) name);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return result;
}
@Override
public Object put(String name, Object object) {
super.put(name, object);
return object;
}
}import com.ql.util.express.ExpressRunner;
import com.ql.util.express.IExpressContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.util.Collections;
import java.util.Map;
/**
* QLExpress 管理器
*
*/
@Slf4j
@Component
public class QLExpressManager implements InitializingBean, ApplicationContextAware {
private ExpressRunner runner = new ExpressRunner(false, false);;
private ApplicationContext applicationContext;
public Object execute(String statement, Map<String, Object> context) throws Exception {
IExpressContext expressContext = new QLExpressContext(context != null ? context : Collections.EMPTY_MAP, applicationContext);
return runner.execute(statement, expressContext, null, true, false);
}
@Override
public void afterPropertiesSet() throws Exception {
runner.addOperatorWithAlias("大于", ">", null);
runner.addOperatorWithAlias("小于", "<", null);
runner.addOperatorWithAlias("等于", "==", null);
runner.addOperatorWithAlias("大于等于", ">=", null);
runner.addOperatorWithAlias("小于等于", "<=", null);
Map<String, RuleHandler> beanMap = applicationContext.getBeansOfType(RuleHandler.class);
beanMap.values().forEach(bean -> {
Method[] methods = bean.getClass().getDeclaredMethods();
for (Method method : methods) {
QlRule qlRule = method.getAnnotation(QlRule.class);
if (qlRule == null) {
continue;
}
try {
runner.addFunctionOfClassMethod(qlRule.methodName(), bean.getClass().getName(), method.getName(),
method.getParameterTypes(), null);
} catch (Exception ex) {
log.error("runner.addFunctionOfClassMethod", ex);
}
}
});
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}import java.lang.annotation.*;
/**
* QLRule 注解,Spring启动时扫描
*
*/
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface QlRule {
/**
* 方法名称
*/
String methodName();
/**
* 方法描述
*/
String desc() default "";
}/**
* 规则处理器
*
*/
public interface RuleHandler {
}
















