Groovy轻量化动态规则引擎的使用,可应用于按大量规则计算获取总分,可以是一个文件,也可以是一段String语句

本文介绍了一个使用Groovy的工具类,该类能够加载并执行Groovy脚本文件或直接执行Groovy字符串内容。通过缓存机制提高了执行效率,并提供了调用Groovy方法的功能,适用于动态计算场景。在Groovy脚本中,通过反射获取并执行匹配的方法,以处理传入的参数,生成计算结果。
摘要由CSDN通过智能技术生成

首先需要引入二个依赖

        <dependency>
            <groupId>org.codehaus.groovy</groupId>
            <artifactId>groovy</artifactId>
            <version>2.5.5</version>
        </dependency>
        <dependency>
            <groupId>org.codehaus.groovy</groupId>
            <artifactId>groovy-jsr223</artifactId>
            <version>2.5.5</version>
        </dependency>

其次便是groovy的工具类,可写到utils中

public class GroovyUtil {

    private static Map<String, GroovyObject> objectCache = new ConcurrentHashMap<>();
    
    //groovy语句在文件中
    public static Object invokeByFilePath(String scriptPath, String method, Object... objects)
            throws IllegalAccessException, InstantiationException, IOException {
        GroovyObject scriptInstance = null;
        String cacheKey = SecureUtil.md5(scriptPath);
        if(objectCache.containsKey(cacheKey)) {
            scriptInstance = objectCache.get(cacheKey);
        }
        else {
            //获取路径资源
            ClassPathResource classPathResource = new ClassPathResource(scriptPath);
            InputStream inputStream =classPathResource.getInputStream();
            String scriptContent = IoUtil.read(inputStream, Charset.defaultCharset());
            GroovyClassLoader classLoader = new GroovyClassLoader();
            //将groovy语句内容转成一个class类
            Class scriptClass = classLoader.parseClass(scriptContent);
            //实例化groovyObject类
            scriptInstance = (GroovyObject) scriptClass.newInstance();
        }
        //执行实例化的groovy类的的method这个方法,这个method方法也就是主方法。
        return scriptInstance.invokeMethod(method, objects);
    }

    //groovy语句是个String时
    public static Object invokeByContent(String scriptContent, String method, Object... objects)
            throws IllegalAccessException, InstantiationException {
        GroovyObject scriptInstance = null;
        String cacheKey = SecureUtil.md5(scriptContent);
        if(objectCache.containsKey(cacheKey)) {
            scriptInstance = objectCache.get(cacheKey);
        }
        else {
            GroovyClassLoader classLoader = new GroovyClassLoader();
            Class scriptClass = classLoader.parseClass(scriptContent);
            scriptInstance = (GroovyObject) scriptClass.newInstance();
        }

        return scriptInstance.invokeMethod(method, objects);
    }

}

调用工具类GroovyUtil的方法执行groovy文件中的指定方法,且将参数传过去

makeLevelDTOList = (List<MakeLevelDTO>)GroovyUtil.invokeByFilePath(
                    "/script/MakeLevel.groovy", "makeList", normList, allLevels, targetLevelCode, outpatients);

 关于groovy文件中的内容,例如我调用的在文件中的这个方法

    public static List<MakeLevelDTO> makeList(List<ICFaInvestigationNorm> normList,
                                              List<ICBmLevel> levelList,
                                              Integer targetLevel,
                                              Integer firstNormValue) {
        init(levelList, targetLevel, firstNormValue);

        Method[] methods = MakeLevel.class.declaredMethods;
        List<MakeLevelDTO> list = new ArrayList<>();
        for(ICFaInvestigationNorm norm : normList) {
            String methodName = null;
            String tempName = "rule" + norm.normCode.replaceAll("\\.", "_");
            for (Method method : methods) {
                if (method.name.equals(tempName)) {
                    methodName = tempName;
                    break;
                }
            }
            if(norm.appendInfo == null) {
                MakeLevelDTO makeLevelDTO = new MakeLevelDTO();
                makeLevelDTO.normCode = norm.normCode;
                makeLevelDTO.wholeScore = 0.00;
                makeLevelDTO.fitTarget = 0;
                makeLevelDTO.fitLevel = 0;
                list.add(makeLevelDTO);
            }
            else {
                methodName = methodName == null ? GENERAL_RULE.get(norm.appendInfo.scoreShow) : methodName;

                if (methodName == null) {
                    continue;
                }

                Method method = MakeLevel.class.getDeclaredMethod(methodName, ICFaInvestigationNorm.class);
                MakeLevelDTO makeLevelDTO = (MakeLevelDTO) method.invoke(null, norm);
                list.add(makeLevelDTO);
            }
        }

        return list;
    }

在方法中也就是通过类反射获取文件中的所有的方法名,然后根据传过来的参数(也就是和写在groovy中的方法名相同的名称),method.invoke去遍历执行传过来的所有方法名参数,也就是执行符合的方法,计算出数据。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值