java-mvel使用记录

本文记录了在Java项目中使用MVEL表达式的经历,包括引入MVEL库,初步测试,添加静态表达式文件,以及在MVEL文件中引入Java包。通过创建MVEL函数文件并利用resolverFactory实现方法缓存,可以便捷地调用预编译的Java方法,适用于动态计算和热编译场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用原因

最近的项目中需要使用到mvel表达式做计算,遍对此进行了了解,在此将使用的经历分享给大家

引入mvel

在此我使用的时maven官方库的最新包,个人建议降2个版本使用,或使用使用人数最多的版本

 <dependency>
            <groupId>org.mvel</groupId>
            <artifactId>mvel2</artifactId>
            <version>2.4.8.Final</version>
 </dependency>

初步测试

mvel表达式的使用很简单,详细使用参考官方文档,这里先写一个简单的测试代码

	public static void main(String[] args){
        //mvel表达式,功能:变量大于10,a加1,小于10则减1
        String expression = "int a = 10;" +
                "if(case1 < 10){System.out.println('less 10');a += 1;}" +
                "else{System.out.println('more then 10'); a -= 1;} return a;";
        //在这个map中放入使用到的变量
        Map vars = new HashMap();
        vars.put("case1", new Integer(12));
        //运行表达式
        Integer result = (Integer) MVEL.eval(expression, vars);

        System.out.println("result: " + result);

    }

mvel表达式中支持对象加‘.’的方式获取变量,如:可以将代码中的case1改为case.case1,同时在vars中放入名为case的对象,case对象中有case1字段。

添加mvel静态表达式

在使用的过程中,总会存在一些公共的方法,类似于java中的util,在resources文件夹中创建名为mvel的文件夹,并创建以mvel为后缀的文件(如mvel-function.mvel)(建议不要使用mvel.mvel这种文件名)
在这里插入图片描述

  1. 构建实际的表达式
 	private static String buildMvelExp(){
        StringBuilder exp = new StringBuilder();
        exp.append("int result = 0;");
        // 使用表达式文件中的方法
        exp.append("if(chgpaymode205(payIntv) < 10){");
        exp.append("result = 10;");
        exp.append("}else{");
        exp.append("result = 20;");
        exp.append("}");
        exp.append("return result;");
        return exp.toString();
    }
  1. 引入相关文件
	public static void main(String[] args) throws Exception{
        String expression = buildMvelExp();

        ParserContext ctx = new ParserContext();

        VariableResolverFactory resolverFactory = new MapVariableResolverFactory();
		// 这里使用的是springboot的文件路径
        Resource resourcce = new ClassPathResource("mvel/mvel-function.mvel");
        File scriptFile = resourcce.getFile();
        MVEL.evalFile(scriptFile, ctx, resolverFactory);
		// 添加使用到的变量
        Map vars = new HashMap();
        vars.put("payIntv", new Integer(15));
        Integer result = (Integer) MVEL.eval(expression, vars, resolverFactory);

        System.out.println("result: " + result);
    }

以上关键在于resolverFactory,编译文件时需要带resolverFactory进行编译,同时运行表达式的使用需要带resolverFactory运行,原因在于编译文件的时候会把编译好的方法放入到resolverFactory中,所以使用的时候可以一次编译后,将resolverFactory作为缓存进行多次使用。
mvel支持添加多个方法文件,如
在这里插入图片描述
其中需要使用同一个resolverFactory。

在mvel静态文件中引入java的包

虽然mvel官方的jar中有ParserContext类,调用ParserContext.addImport()引入包,但是试了几次都没成功QAQ,所以这里只说我实验通过的。

  1. 在独立的mvel文件中直接引入
    如图:
    在这里插入图片描述
    引入方法类似于java文件的的引入方法
  2. 在表达式中直接使用
    这里复用上面构建mvel表达式的
	private static String buildMvelExp(){
        StringBuilder exp = new StringBuilder();
        // 引入使用的java文件
        exp.append("import java.text.SimpleDateFormat;");
        exp.append("import java.util.*");
        exp.append("result = '';");
        // 使用表达式文件中的方法
        exp.append("if(chgpaymode205(payIntv) < 10){");
        exp.append("result = new SimpleDateFormat('yyyy-MM-dd').format(nowTime);");
        exp.append("}else{");
        exp.append("result = new SimpleDateFormat('yyyy-MM-dd').format(nowTime);");
        exp.append("}");
        exp.append("return result;");
        return exp.toString();
    }

这种用法可以引用已编译好的java方法,可以用于类似于热编译的场景,例如:可以先实时编译java代码,之后再表达式中调用编译好的java方法


目前就这样,之后再做更精细的操作教程,请谅解!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值