疯狂Activiti6.0连载(15)DMN规则匹配表达式


声明:本文转载自https://my.oschina.net/JavaLaw/blog/1573703,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

本文节选自《疯狂Workflow讲义(第2版)》

疯狂Activiti电子书:https://my.oschina.net/JavaLaw/blog/1570397

DMN规则匹配表达式

        规则引擎中的输入参数与输出结果,可以在inputExpression元素下使用MVEL表达式,这样就意味着在规则匹配以及结果处理上,都使得规则引擎变得很灵活,本小节将以MVEL为基础,讲述Activiti规则引擎在匹配上的原理。

MVEL表达式简介

        MVEL是一款基于Java程序的表达式语言,它支持大部分的Java语法,当前版本为2.0。使用MVEL,可以在XML文档中实现获取属性值、进行运算、设置结果等功能,除此之外,还可以对其进行扩展,实现更为复杂的需求。目前很多开源项目都使用了MVEL表达式,例如Drools、Apache Camel等框架。Activiti规则引擎中也使用了MVEL,因此允许在DMN文件使用跟以下代码片断类似的表达式:

person.name == ‘Angus’ && person.age == 30

        以上表达式判断person对象的name属性值是否为“Angus”以及age属性值是否为30,表达式的执行结果为true或者false。本小节将先讲述MVEL的简单使用。

执行第一个表达式

        下面编写一个最简单的表式,使用MVEL的API进行编译与执行,见代码清单15-13。

        代码清单15-13:codes\15\15.5\mvel-test\src\org\crazyit\activiti\FirstTest.java

    // 进行编译     Serializable compiledExpression = MVEL         .compileExpression("personName == 'Angus'");     // 设置执行参数     Map<String, String> params = new HashMap<String, String>();     params.put("personName", "Angus");     // 执行表达式并返回结果     Boolean result = MVEL.executeExpression(compiledExpression, params,         Boolean.class);     // 控制台输出结果     System.out.println("表达式第一次执行结果:" + result);     // 传入其他 参数,结果将为false     params.put("personName", "Paris");     // 再次执行表达式     result = MVEL.executeExpression(compiledExpression, params,         Boolean.class);     // 输出结果     System.out.println("表达式第二次执行结果:" + result); 

        代码清单15-13的粗体字代码,使用了MVEL的API进行表达式编译和执行。先编译了“personName == ‘Angus’”的表达式,表示personName这个运行参数的值是否为“Angus”,在运行时,传入参数Map即可。代码清单15-13执行了两次表达式,第一次执行结果为true,第二次传入了不等的参数,因此执行结果为false。运行代码清单15-13,输出结果如下:

表达式第一次执行结果:true 表达式第二次执行结果:false 

使用对象执行表达式

        MVEL表达式中,也支持传入对象,并可以获取对象的值或者方法返回值来进行运算,代码清单15-14中的表达式,使用了Java对象。

        代码清单15-14:codes\15\15.5\mvel-test\src\org\crazyit\activiti\ObjectTest.java

        // 进行编译         Serializable compiledExpression = MVEL                 .compileExpression("person.name == 'Angus' && person.age == 30");         // 设置执行参数         Map<String, Object> params = new HashMap<String, Object>();         // 设置名称与年龄均符合条件         Person p = new Person();         p.setName("Angus");         p.setAge(30);         params.put("person", p);         // 执行表达式并返回结果,输出为true         Boolean result = MVEL.executeExpression(compiledExpression, params,                 Boolean.class);         System.out.println("第一次执行表达式结棍:" + result);         // 修改参数年龄         Person p2 = new Person();         p2.setName("Angus");         p2.setAge(20);         params.put("person", p2);         // 重新执行表达式,结果false         result = MVEL.executeExpression(compiledExpression, params,                 Boolean.class);         System.out.println("第二次执行表达式结果:" + result); 

        代码清单15-14中,执行的表达式为,person实例的name属性值是否为“Angus”,并且person的age属性值为30,这两个条件都符合时,表达式返回true。代码清单15-14中的粗体字代码,分别执行了两次表达,第一次的参数完全符合条件,第二次执行的参数age不符合条件,最终输出false。执行代码清单15-14,输出结果如下:

第一次执行表达式结棍:true 第二次执行表达式结果:false 

规则引擎规则匹配逻辑

        在DMN文件中定义规则的输入参数和输出结果的时候,可以在text元素下面写入MVEL表达式,以下代码片断为rule元素定义:

            <rule>                 <inputEntry id="inputEntry1">                     <text>                         <![CDATA[                              执行匹配的MVEL表达式                         ]]>                     </text>                 </inputEntry>                 <outputEntry id="outputEntry1">                     <text>                         <![CDATA[                               处理输出结果的MVEL表达式                         ]]>                     </text>                 </outputEntry>             </rule> 

        以上代码片断的粗体字代码,在inputEntry下的text元素,可以使用MVEL表达式,但要注意的是,该表达式的结果必须为Boolean类型,因为该表达式决定规则是否匹配。在outputEntry下的text元素,同样可添加MVEL表达式,该表达式的计算结果就是规则的返回结果,注意要与决策表的输出结果类型相匹配,请见以下代码片断:

            <output id="outputId" label="Output 1" name="myResult" typeRef="number" />             <rule>                 <inputEntry id="inputEntry1">                     <text>                         <![CDATA[                              执行匹配的MVEL表达式                          ]]>                     </text>                 </inputEntry>                 <outputEntry id="outputEntry1">                     <text>                         <![CDATA[                               输出结果的MVEL表达式,要返回数字                         ]]>                     </text>                 </outputEntry>             </rule> 

        以上代码片断的粗体字代码,定义了输出结果的类型为“number”,如果匹配到的规则,输出结果的MVEL表达返回的是字符串,则会报出异常。

        Activiti规则引擎在读取inputEntry配置的MVEL表达式时,会进处理,将输入参数的名称添加到配置的MVEL表达式前面,组合成新的表达式让MVEL去执行,在组合成新的表达式时,会有两种处理方式,请见代码清单15-15。

        代码清单15-15:codes\15\15.5\dmn-mvel\resource\dmn\GetExpression.dmn

            <rule>                 <inputEntry id="inputEntry1">                     <text>                         <!-- 生成的表达式为 personName.equals('Angus')  -->                         <![CDATA[                              .equals('Angus')                           ]]>                     </text>                 </inputEntry>             </rule>             <rule>                 <inputEntry id="inputEntry2">                     <text>                         <!-- 生成的表达式为  personName == 'Angus'  -->                         <![CDATA[                              == 'Angus'                           ]]>                     </text>                 </inputEntry>             </rule> 

        代码清单15-15中定义了两个规则,第一个规则定义的MVEL表达式为“.equals”,此种情况下,Activiti会自动生成“personName.equals”这样的语句,personName是输入参数的名称。第二个规则定义的表达式为“== ‘Angus’”,则Activiti会自动生成“personName == ‘Angus’”,即自动加上参数名称与一个空格。对比这两种情况可知,Activiti会根据我们定义的表达式是否以“.”(点)开头,然后分别作两种处理。在写规则的MVEL表达式时,要注意这个细节。

本文节选自《疯狂Workflow讲义(第2版)》

疯狂Activiti电子书:https://my.oschina.net/JavaLaw/blog/1570397

本书代码目录:https://gitee.com/yangenxiong/CrazyActiviti

本文发表于2017年11月15日 10:33
(c)注:本文转载自https://my.oschina.net/JavaLaw/blog/1573703,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 2580 讨论 0 喜欢 0

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

你要过得好哇,这样我才能恨你啊,你要是过得不好,我都不知道该恨你还是拥抱你啊。

直抵黄龙府,与诸君痛饮尔。

那时陪伴我的人啊,你们如今在何方。

不出意外的话,我们再也不会见了,祝你前程似锦。

这世界真好,吃野东西也要留出这条命来看看

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1