java-mvel使用记录3——缓存刷新问题

本文记录了在Java MVEL中遇到的缓存刷新问题及其解决方案。通过去除对函数体的缓存,添加单个函数体的编译,实现了按需修改resolverFactory的功能。详细介绍了实现逻辑,包括引用类合并、VariableResolver合并和resolver合并的过程,以及源码中的关键字解析。
摘要由CSDN通过智能技术生成

起因

事情的起因源自上篇文章中源码分析的原因:要实现按需修改resolverFactory中缓存的参数,上篇及上上篇中为了实现功能添加了很多不必要的缓存,所以这篇文章中写一下我新的实现方法

改动点

去除对函数体的缓存

在上上篇文章中在缓存中保存了函数体,在新的解决方法中直接去掉就行了,因为不需要

添加对单个函数体的编译

由于采用的是按需添加缓存,但没有减少,所以当函数加入到resolverFactory的Map中后,除非是重启服务,否则只有全部清空,MapVariableResolverFactory中提供了clear()方法,下面是单个函数体编译的代码

	public MapVariableResolverFactory rebuildVariableResolverFactoryByStr(String expStr) {
        MapVariableResolverFactory resolverFactory = new MapVariableResolverFactory();
        ParserContext ctx = new ParserContext();
        try{
            char[] charArr = expStr.toCharArray();

            MVEL.eval(charArr, ctx, resolverFactory);
        }catch (Exception e){
            e.printStackTrace();
            return null;
        }
        return resolverFactory;
    }

实现逻辑

这里的实现逻辑是

  • 从缓存中获取原来的resolverFactory
MapVariableResolverFactory resolverFactory = (MapVariableResolverFactory) getVariableResolverFactory();
  • 将修改或新增的函数单独编译,调用上一步的编译方法
	//newFunction.getFunctionEntity()为函数体,也就是函数的字符串
 MapVariableResolverFactory newFuncResolverFactory = calculatorBuild.rebuildVariableResolverFactoryByStr(newFunction.getFunctionEntity());
  • 进行相关参数的合并
    这里进行3个参数的合并,下面一一说明:

    • 引用类合并
      必须说明,在进行操作的时候一定要判断新编译的函数中是否存在引用类,不存在和跳过这一步,原理是:在mvel的编译行为进行的时候会对你传入的函数字符串进行扫描,如果发现import或import-static关键字就会生成ClassImportResolverFactory,并在这个类中保存引用的对象,以Map<String, Object> 的形式进行保存,其中Object为引用类的Class对象,在ClassImportResolverFactory中只提供了添加方法,不提供获取,代码如下,感兴趣的自行观看
      private Map<String, Object> dynImports;
      ...
      public Class addClass(Class clazz) {
      if (this.dynImports == null) {
      
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值