一、规则引擎的作用
将复杂的if else判断剥离出来
二、使用
2.1、引入POM
< ! --easy rules核心库-->
< dependency>
< groupId> org.jeasy< /groupId>
< artifactId> easy-rules-core< /artifactId>
< version> 3.3 .0 < /version>
< /dependency>
< ! --规则定义文件格式,支持json,yaml等-->
< dependency>
< groupId> org.jeasy< /groupId>
< artifactId> easy-rules-support< /artifactId>
< version> 3.3 .0 < /version>
< /dependency>
< ! --支持mvel规则语法库-->
< dependency>
< groupId> org.jeasy< /groupId>
< artifactId> easy-rules-mvel< /artifactId>
< version> 3.3 .0 < /version>
2.2、编写规则
2.2.1、注解
package com. xx. rule. number ;
import org. jeasy. rules. annotation. Action ;
import org. jeasy. rules. annotation. Condition ;
import org. jeasy. rules. annotation. Fact ;
import org. jeasy. rules. annotation. Rule ;
@Rule ( name = "被3整除" , description = "number如果被3整除,打印:number is 3" , priority = 1 )
public class ThreeRule {
@Condition
public boolean isThree ( @Fact ( "number" ) int number) {
return number % 3 == 0 ;
}
@Action
public void threeAction ( @Fact ( "number" ) int number) {
System . out. println ( number + ":可以被3整除" ) ;
}
}
2.2.2、表达式
MVELRule ageRule = new MVELRule ( )
. name ( "age rule" )
. description ( "判断这个人是否成年,是否可以饮酒" )
. priority ( 1 )
. when ( "person.age > 18" ) . then ( "person.setAdult(true);" ) ;
2.2.3 yml配置文件
name : "alcohol rule"
description : "children are not allowed to buy alcohol"
priority : 2
condition : "person.isAdult() == false"
actions :
- "System.out.println(\"你还未满18岁!\");"
2.2.4 组合规则
UnitRuleGroup myUnitRuleGroup = new UnitRuleGroup ( "myUnitRuleGroup" , "组合规则" ) ;
myUnitRuleGroup. addRule ( ageRule) ;
myUnitRuleGroup. addRule ( alcoholRule) ;
2.2.5 组合规则说明
类 说明 UnitRuleGroup 要么应用所有规则,要么不应用任何规则(AND逻辑) ActivationRuleGroup 它触发第一个适用规则,并忽略组中的其他规则(XOR逻辑) ConditionalRuleGroup 如果具有最高优先级的规则计算结果为true,则触发其余规则
2.2.6 字段说明
字段 说明 name 规则名称 description 规则描述 priority 规则执行顺序,越小越先执行 condition 条件 actions 满足条件之后的执行动作
2.3、规则使用
2.3.1、注解规则使用
package com. xx ;
import com. xx. rule. number. ThreeRule ;
import org. jeasy. rules. api. Facts ;
import org. jeasy. rules. api. Rules ;
import org. jeasy. rules. api. RulesEngine ;
import org. jeasy. rules. core. DefaultRulesEngine ;
public class Main {
public static void main ( String [ ] args) {
RulesEngine rulesEngine = new DefaultRulesEngine ( ) ;
Rules rules = new Rules ( ) ;
rules. register ( new ThreeRule ( ) ) ;
Facts facts = new Facts ( ) ;
for ( int i = 1 ; i <= 50 ; i++ ) {
facts. put ( "number" , i) ;
rulesEngine. fire ( rules, facts) ;
System . out. println ( ) ;
}
}
}
2.3.2、表达式和yml规则使用
package com. xx ;
import com. xx. domain. Person ;
import org. jeasy. rules. api. Facts ;
import org. jeasy. rules. api. Rule ;
import org. jeasy. rules. api. Rules ;
import org. jeasy. rules. api. RulesEngine ;
import org. jeasy. rules. core. DefaultRulesEngine ;
import org. jeasy. rules. core. RuleBuilder ;
import org. jeasy. rules. mvel. MVELRuleFactory ;
import org. jeasy. rules. support. YamlRuleDefinitionReader ;
import org. springframework. util. ResourceUtils ;
import java. io. FileReader ;
public class ShopMain {
public static void main ( String [ ] args) throws Exception {
Person person = new Person ( ) ;
person. setName ( "tom" ) ;
person. setAge ( 20 ) ;
Facts facts = new Facts ( ) ;
facts. put ( "person" , person) ;
Rule ageRule = new RuleBuilder ( )
. name ( "age rule" )
. description ( "判断这个人是否成年,是否可以饮酒" )
. when ( e -> Integer . parseInt ( e. get ( "person.age" ) ) > 18 )
. then ( e -> e. put ( "person.adult" , true ) )
. build ( ) ;
Rule alcoholRule = new MVELRuleFactory ( new YamlRuleDefinitionReader ( ) ) .
createRule ( new FileReader ( ResourceUtils . getFile ( "classpath:alcohol-rule.yml" ) ) ) ;
Rules rules = new Rules ( ) ;
rules. register ( ageRule) ;
rules. register ( alcoholRule) ;
RulesEngine rulesEngine = new DefaultRulesEngine ( ) ;
rulesEngine. fire ( rules, facts) ;
System . out. println ( person) ;
}
}
2.3.1、规则引擎可配参数
参数 说明 skipOnFirstAppliedRule 当一个规则成功应用时,跳过余下的规则 skipOnFirstFailedRule 当一个规则失败时,跳过余下的规则 skipOnFirstNonTriggeredRule 当一个规则未触发时,跳过余下的规则 rulePriorityThreshold 当优先级超过指定的阈值时,跳过余下的规则
通过如下方式设置
RulesEngineParameters parameters = new RulesEngineParameters ( ) . skipOnFirstAppliedRule ( true ) ;
RulesEngine rulesEngine = new DefaultRulesEngine ( parameters) ;