一、规则引擎的作用
将复杂的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) ;