Fel是开放的,引擎执行中的多个模块都可以扩展或替换。Fel的执行主要是通过函数实现,运算符(+、-等都是Fel函数),所有这些函数都是可以替换的,扩展函数也非常简单。

   Fel有双引擎,同时支持解释执行和编译执行。可以根据性能要求选择执行方式。编译执行就是将表达式编译成字节码(生成java代码和编译模块都是可以扩展和替换的)

 FEL可以进行算数运算以及逻辑运算,也可以调用类的静态方法、非静态方法。 

 

只需要一个jar包:

 

 1.  简单使用

 1.  简单计算

复制代码

    private static void calculate() {
        // 算数运算
        FelEngine fel = new FelEngineImpl();
        Object result = fel.eval("1.5898*1+75");
        System.out.println(result);

        // 逻辑运算
        Object result2 = fel.eval("1 == 2 || '1'.equals('1')");
        System.out.println(result2);
    }

复制代码

 结果:

76.5898
true

 

2.   变量用法

复制代码

    private static void variables() {
        // 变量
        FelEngine fel = new FelEngineImpl();
        FelContext ctx = fel.getContext();
        ctx.set("单价", 1.5898);
        ctx.set("数量", 1);
        ctx.set("运费", 75);

        Object result = fel.eval("单价*数量+运费");
        System.out.println(result);
    }

复制代码

结果:

76.5898

 

3.  访问对象的方法

复制代码

    private static void object() {
        FelEngine fel = new FelEngineImpl();
        FelContext ctx = fel.getContext();
        User user = new User(1, "qqq", "中国北京");
        ctx.set("user", user);

        Map<String, String> map = new HashMap<String, String>();
        map.put("name", "qqq");

        ctx.set("map", map);

        // 调用user.getName()方法。
        System.out.println(fel.eval("user.name"));

        // map.name会调用map.get("name");
        System.out.println(fel.eval("map.name"));
    }

复制代码

qqq
qqq

 

例如:访问StringUtils方法的第一种方式

复制代码

    private static void method() {
        FelEngine fel = new FelEngineImpl();
        FelContext ctx = fel.getContext();
        ctx.set("out", System.out);
        ctx.set("StringUtils", new StringUtils());

        Object eval = fel.eval("out.println('Hello Everybody'.substring(6))");
        Object eval2 = fel.eval("StringUtils.isEmpty('')");
        System.out.println(eval);
        System.out.println(eval2);
    }

复制代码

 

4.  访问静态方法

  访问StringUtils的方法:

复制代码

    private static void staticMethod() {
        // 调用Math.min(1,2)
        Object eval = FelEngine.instance.eval("$('Math').min(1,2)");
        System.out.println(eval);

        // 调用Stringutils的方法
        Object eval1 = FelEngine.instance.eval("$('org.apache.commons.lang.StringUtils').isEmpty('123')");
        System.out.println(eval1);
    }

复制代码

结果:

1
false

 

注意:如果不加包名会默认调用java.lang包下的,即使类是默认包的也会访问java.lang包的,所以最好加包名。 

 

5.  访问集合

复制代码

    private static void collections() {
        FelEngine fel = new FelEngineImpl();
        FelContext ctx = fel.getContext();

        // 数组
        int[] intArray = { 1, 2, 3 };
        ctx.set("intArray", intArray);
        // 获取intArray[0]
        String exp = "intArray[0]";
        System.out.println(exp + "->" + fel.eval(exp));

        // List
        List<Integer> list = Arrays.asList(1, 2, 3);
        ctx.set("list", list);
        // 获取list.get(0)
        exp = "list[0]";
        System.out.println(exp + "->" + fel.eval(exp));

        // 集合
        Collection<String> coll = Arrays.asList("a", "b", "c");
        ctx.set("coll", coll);
        // 获取集合最前面的元素。执行结果为"a"
        exp = "coll[0]";
        System.out.println(exp + "->" + fel.eval(exp));

        // 迭代器
        Iterator<String> iterator = coll.iterator();
        ctx.set("iterator", iterator);
        // 获取迭代器最前面的元素。执行结果为"a"
        exp = "iterator[0]";
        System.out.println(exp + "->" + fel.eval(exp));

        // Map
        Map<String, String> m = new HashMap<String, String>();
        m.put("name", "HashMap");
        ctx.set("map", m);
        exp = "map.name";
        System.out.println(exp + "->" + fel.eval(exp));

        // 多维数组
        int[][] intArrays = { { 11, 12 }, { 21, 22 } };
        ctx.set("intArrays", intArrays);
        exp = "intArrays[0][0]";
        System.out.println(exp + "->" + fel.eval(exp));

        // 多维综合体,支持数组、集合的任意组合。
        List<int[]> listArray = new ArrayList<int[]>();
        listArray.add(new int[] { 1, 2, 3 });
        listArray.add(new int[] { 4, 5, 6 });
        ctx.set("listArray", listArray);
        exp = "listArray[0][0]";
        System.out.println(exp + "->" + fel.eval(exp));
    }

复制代码

 

2.  高级用法

1.  编译运行

复制代码

    private static void compile() {
        FelEngine fel = new FelEngineImpl();
        FelContext ctx = fel.getContext();
        ctx.set("单价", 1.5898);
        ctx.set("数量", 1);
        ctx.set("运费", 75);
        Expression exp = fel.compile("单价*数量+运费", ctx);
        Object result = exp.eval(ctx);
        System.out.println(result);
    }

复制代码

结果:

76.5898

 

2.  自定义context

复制代码

    private static void myContext() {
        FelContext ctx = new AbstractContext() {
            @Override
            public Object get(String arg0) {
                System.out.println(arg0);
                return "111222";
            }
        };

        FelEngine fel = new FelEngineImpl(ctx);
        Object eval = fel.eval("天气 + 温度");
        System.out.println(eval);
    }

复制代码

结果:

天气
温度
111222111222

 

3.  自定义函数

复制代码

    private static void newFun() {
        // 定义hello函数
        Function fun = new CommonFunction() {
            public String getName() {
                return "hello";
            }

            @Override
            public Object call(Object[] arguments) {
                Object msg = null;
                if (arguments != null && arguments.length > 0) {
                    msg = arguments[0];
                }
                return ObjectUtils.toString(msg);
            }

        };

        FelEngine e = new FelEngineImpl();
        // 添加函数到引擎中。
        e.addFun(fun);
        String exp = "hello(23, 'fel', 1)";

        // 解释执行
        Object eval = e.eval(exp);
        System.out.println("hello " + eval);
        // 编译执行
        Expression compile = e.compile(exp, null);
        eval = compile.eval(null);
        System.out.println("hello " + eval);
    }

复制代码

结果:

hello 23
hello 23