轻量级规则引擎

一、aviator规则引擎

依赖:

<!-- https://mvnrepository.com/artifact/com.googlecode.aviator/aviator -->
        <dependency>
            <groupId>com.googlecode.aviator</groupId>
            <artifactId>aviator</artifactId>
            <version>5.1.4</version>
        </dependency>

代码:

import com.googlecode.aviator.*;
import com.googlecode.aviator.runtime.function.AbstractFunction;
import com.googlecode.aviator.runtime.function.FunctionUtils;
import com.googlecode.aviator.runtime.type.AviatorDouble;
import com.googlecode.aviator.runtime.type.AviatorObject;
import com.googlecode.aviator.script.AviatorScriptEngine;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class AviatorDemo {
    
    


    public static void main(String[] args) throws IOException, ScriptException {
    
    
        test1();
        test2();
        test3();
        test4();
        test5();
    }


    public static void test1(){
    
    
        String name = "测试";
        Map<String, Object> env = new HashMap<>(1);
        env.put("name", name);
        String result = (String) AviatorEvaluator.execute(" 'hello ' + name ", env);
        System.out.println(result);
    }


    private static void test2() throws IOException {
    
    
        //注册函数
        AviatorEvaluator.addFunction(new AddFunction());
        System.out.println(AviatorEvaluator.execute("add(1, 2)"));           // 3.0
        System.out.println(AviatorEvaluator.execute("add(add(1, 2), 100)")); // 103.0
    }


    private static void test3(){
    
    
        String expression = "a-(b-c) > 100";
        Expression compiledExp = AviatorEvaluator.compile(expression);
        // Execute with injected variables.
        Boolean result = (Boolean) compiledExp.execute(compiledExp.newEnv("a", 100.3, "b", 45, "c", -199.100));
        System.out.println(result);
        // Compile a script
        Expression script = AviatorEvaluator.getInstance().compile("println('Hello, AviatorScript!');");
        script.execute();
    }

    /**
     * ## examples/statements.av
     * let a = 1;
     * let b = 2;
     * c = a + b;
     * @throws IOException
     */
    private static void test4() throws IOException {
    
    
        Expression exp = AviatorEvaluator.getInstance().compileScript("examples/statements.av");
        Object result = exp.execute();
        System.out.println(result);
    }


    private static void test5() throws ScriptException {
    
    
        final ScriptEngineManager sem = new ScriptEngineManager();
        ScriptEngine engine = sem.getEngineByName("AviatorScript");
        AviatorEvaluatorInstance instance = ((AviatorScriptEngine) engine).getEngine();
        // Use compatible feature set
        instance.setOption(Options.FEATURE_SET, Feature.getCompatibleFeatures());
        // Doesn't support if in compatible feature set mode.
        engine.eval("if(true) { println('support if'); }");
    }

    /**
     * 自定义函数
     */
    static class AddFunction extends AbstractFunction {
    
    
        @Override
        public AviatorObject call(Map<String, Object> env, AviatorObject arg1, AviatorObject arg2) {
    
    
            Number left = FunctionUtils.getNumberValue(arg1, env);
            Number right = FunctionUtils.getNumberValue(arg2, env);
            return new AviatorDouble(left.doubleValue() + right.doubleValue());
        }
        @Override
        public String getName() {
    
    
            return "add";
        }
    }

}

二、Groovy规则引擎

依赖:

        <dependency>
            <groupId>org.codehaus.groovy</groupId>
            <artifactId>groovy</artifactId>
            <version>3.0.3</version>
        </dependency>
         <dependency>
            <groupId>org.codehaus.groovy</groupId>
            <artifactId>groovy-all</artifactId>
            <version>3.0.3</version>
        </dependency>

代码:

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

public class GroovyDemo {
    
    

    public String testQuery(long id){
    
    
        return "Test query success, id is " + id;
    }

    public static void main(String[] args) {
    
    
        test1();
    }

    private static void test1(){
    
    
        Binding groovyBinding = new Binding();
        GroovyShell groovyShell = new GroovyShell(groovyBinding);
        String scriptContent = "import com.citydo.faceadd.aviator.GroovyDemo\n" +
                "def query = new GroovyDemo().testQuery(1L);\n" +
                "query";
        Script script = groovyShell.parse(scriptContent);
        System.out.println(script.run());
    }


    private static void test2(){
    
    
        Binding groovyBinding = new Binding();
        groovyBinding.setVariable("GroovyDemo", new GroovyDemo());
        GroovyShell groovyShell = new GroovyShell(groovyBinding);
        String scriptContent = "def query = GroovyDemo.testQuery(2L);\n" +
                "query";
        Script script = groovyShell.parse(scriptContent);
        System.out.println(script.run());

    }

}

import groovy.lang.Binding;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Map;

@Configuration
public class GroovyBindingConfig implements ApplicationContextAware {
    
    

    private ApplicationContext applicationContext;

    @Bean("groovyBinding")
    public Binding groovyBinding() {
    
    
        Binding groovyBinding = new Binding();

        Map<String, Object> beanMap = applicationContext.getBeansOfType(Object.class);
        //遍历设置所有bean,可以根据需求在循环中对bean做过滤
        for (String beanName : beanMap.keySet()) {
    
    
            groovyBinding.setVariable(beanName, beanMap.get(beanName));
        }
        return groovyBinding;
    }

    /*@Bean("groovyBinding1")
    public Binding groovyBinding1() {
        Map<String, Object> beanMap = applicationContext.getBeansOfType(Object.class);
        return new Binding(beanMap); //如果不需要对bean做过滤,直接用beanMap构造Binding对象即可
    }*/

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
    
    
        this.applicationContext = applicationContext;

    }
}
import groovy.lang.Binding;
import groovy.lang.GroovyClassLoader;
import groovy.lang.GroovyShell;
import groovy.lang.Script;
import org.codehaus.groovy.control.CompilerConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.citydo.faceadd.aviator.GroovyDemo;

import javax.annotation.PostConstruct;

@RestController
@RequestMapping("/groovy/script")
public class GroovyScriptController {
    
    

    @Autowired
    private Binding groovyBinding;

    private GroovyShell groovyShell;

    @PostConstruct
    public void init(){
    
    
        GroovyClassLoader groovyClassLoader = new GroovyClassLoader(this.getClass().getClassLoader());
        CompilerConfiguration compilerConfiguration = new CompilerConfiguration();
        compilerConfiguration.setSourceEncoding("utf-8");
        compilerConfiguration.setScriptBaseClass(GroovyDemo.class.getName());

        groovyShell = new GroovyShell(groovyClassLoader, groovyBinding, compilerConfiguration);
    }

    @RequestMapping(value = "/execute", method = RequestMethod.POST)
    public String execute(@RequestBody String scriptContent) {
    
    
        Script script = groovyShell.parse(scriptContent);
        return String.valueOf(script.run());
    }
}

参考:https://www.yuque.com/boyan-avfmj/aviatorscript/fycwgt
参考:https://www.jianshu.com/p/c7803626c09d

猜你喜欢

转载自blog.csdn.net/qq_32447301/article/details/108818967