java 使用 groovy 做轻量级规则引擎

原创
2020/08/04 12:49
阅读数 5.4K

    /*
     * <dependency>

       <groupId>org.codehaus.groovy</groupId>
     * <artifactId>groovy-all</artifactId>

<version>2.4.7</version>

      </dependency>
     */

 

import groovy.lang.Binding;
import groovy.lang.GroovyShell;
import groovy.lang.Script;

public class AnalyzeCalculate {

    /**
     * 测试
     *
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {

 

  //自定义变量 设置 变量
        String s = "$price";
        String str = " if ($price >2) { b = 35};return b;";

        Binding binding = new Binding();
        // 判断是否包含变量$price
        if (str.contains(s)) {
            // 如果 是运单价格 变量price
            Double price = 250.0;// 通过函数获取值 赋值。
            binding.setVariable("$price", price);

        } else {
            System.out.println(str.startsWith(s));
        }

        GroovyShell shell = new GroovyShell(binding);

        Object F1 = shell.evaluate(str);// "P2=F*F1 + T*T1 +A*A1 +P*P1; return P2 ");
        System.out.println("条件计算:" + F1);

        countPrice();
        // evalScriptText();
        // evalScriptTextFull();
        // evalScript();

    }

    // 自定义公式条件
    public static void countPrice() {

        String str = "         if (yundan >500)  \r\n" + "            {a1 = (yundan * 1.4) /2} \r\n"
                + "             else if (yundan <=200)  \r\n" + "        {a1=  yundan *1.2} \r\n"
                + "         else {a1 =0} \r\n" + "         if (price >50000)  \r\n"
                + "                    {a2 = (price * 1.7) /2} \r\n" + "         else if (price <=2000)  \r\n"
                + "            {a2=  price *3}\r\n" + "         else {a2 =0} \r\n" + "         if (totalprice >500000 ) \r\n"
                + "            {a3 = (totalprice * 0.7) /2} \r\n" + "         else if (totalprice <=200000) \r\n"
                + "        {a3=  totalprice *0.2}\r\n" + "         else {a3 =0} \r\n" + "         \r\n"
                + "        if (comment >50000 ) \r\n" + "            {a4 = (comment * 1.7) /2} \r\n"
                + "         else if (comment <=5 ) \r\n" + "            {a4=  comment *0.6}\r\n"
                + "         else {a4 =0} \r\n" + "         a =a1+a2+a3+a4;\r\n" + "       return a;";

        Binding binding = new Binding();
        // 值
        binding.setVariable("yundan", 150);
        binding.setVariable("price", 60000);
        binding.setVariable("totalprice", 600000);
        binding.setVariable("comment", 4);

        binding.setVariable("language", "Groovy");

        GroovyShell shell = new GroovyShell(binding);

        Object F1 = shell.evaluate(str);// "P2=F*F1 + T*T1 +A*A1 +P*P1; return P2 ");
        System.out.println("条件计算:" + F1);
        double d = (150 * 1.2) + (60000 * 1.7) / 2 + (600000 * 0.7) / 2 + 4 * 0.6;
        System.out.println("手动计算结果:" + d);
        // Object F2 = shell.evaluate("P1=P0*(0.055*0.20+1.0011)+A; return P1 ");

    }

    public static void evalScriptText() throws Exception {
        // groovy.lang.Binding
        Binding binding = new Binding();
        GroovyShell shell = new GroovyShell(binding);

        binding.setVariable("name", "zhangsan");
        shell.evaluate("println 'Hello World! I am ' + name;");
        // 在script中,声明变量,不能使用def,否则scrope不一致.
        shell.evaluate("date = new Date();");
        Date date = (Date) binding.getVariable("date");
        System.out.println("Date:" + date.getTime());
        // 以返回值的方式,获取script内部变量值,或者执行结果
        // 一个shell实例中,所有变量值,将会在此"session"中传递下去."date"可以在此后的script中获取
        Long time = (Long) shell.evaluate("def time = date.getTime(); return time;");
        System.out.println("Time:" + time);
        binding.setVariable("list", new String[] { "A", "B", "C" });
        // invoke method
        String joinString = (String) shell.evaluate("def call(){return list.join(' - ')};call();");
        System.out.println("Array join:" + joinString);
        shell = null;
        binding = null;
    }

    /**
     * 运行完整脚本
     *
     * @throws Exception
     */
    public static void evalScriptTextFull() throws Exception {
        StringBuffer buffer = new StringBuffer();
        // define API
        buffer.append("class User{").append("String name;Integer age;")
                // .append("User(String name,Integer age){this.name = name;this.age = age};")
                .append("String sayHello(){return 'Hello,I am ' + name + ',age ' + age;}}\n");
        // Usage
        buffer.append("def user = new User(name:'zhangsan',age:1);").append("user.sayHello();");
        // groovy.lang.Binding
        Binding binding = new Binding();
        GroovyShell shell = new GroovyShell(binding);
        String message = (String) shell.evaluate(buffer.toString());
        System.out.println(message);
        // 重写main方法,默认执行
        String mainMethod = "static void main(String[] args){def user = new User(name:'lisi',age:12);print(user.sayHello());}";
        shell.evaluate(mainMethod);
        shell = null;
    }

    /**
     * 以面向"过程"的方式运行脚本
     *
     * @throws Exception
     */
    public static void evalScript() throws Exception {
        Binding binding = new Binding();
        GroovyShell shell = new GroovyShell(binding);
        // 直接方法调用
        // shell.parse(new File(//))
        Script script = shell.parse("def join(String[] list) {return list.join('--');}");
        String joinString = (String) script.invokeMethod("join", new String[] { "A1", "B2", "C3" });
        System.out.println(joinString);
        //// 脚本可以为任何格式,可以为main方法,也可以为普通方法
        // 1) def call(){...};call();
        // 2) call(){...};
        script = shell.parse("static void main(String[] args){i = i * 2;}");
        script.setProperty("i", new Integer(10));
        script.run();// 运行,
        System.out.println(script.getProperty("i"));
        // the same as
        System.out.println(script.getBinding().getVariable("i"));
        script = null;
        shell = null;
    }

}

展开阅读全文
def
加载中
点击引领话题📣 发布并加入讨论🔥
打赏
0 评论
0 收藏
0
分享
返回顶部
顶部