【脚本】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 {
}