准备
首先引入依赖
org.jeasy
easy-rules-core
3.3.0
org.jeasy
easy-rules-mvel
3.3.0
复制代码
easy-rules-core是easy-rules的核心依赖,必不可少,而easy-rules-mvel是用于mvel的方式创建rule,mvel的方式创建rule比较灵活,可以随时修改rule规则和action逻辑。
简单使用
定义rule
@Rule(name = "被2整除")
public class TwoRule {
@Condition
public boolean isTwo(@Fact("num") int num){
System.out.println("---isTwo----run----");
return num % 2 == 0;
}
@Action
public void action(@Fact("num") int num){
System.out.println(num + " 被2整除");
}
@Priority
public int getPriority(){
return 1;
}
}
@Rule(name = "被3整除")
public class ThreeRule {
@Condition //条件判断注解:如果return true, 执行Action
public boolean isThree(@Fact("num") int num){
System.out.println("---isThree----run----");
return num % 3 == 0;
}
@Action
public void action(@Fact("num") int num){
System.out.println(num + " 被3整除");
}
@Priority //优先级注解:return 数值越小,优先级越高
public int getPriority(){
return 2;
}
}
@Rule(name = "被2和3同时整除")
public class TwoThreeRuleUnitGroup extends UnitRuleGroup {
public TwoThreeRuleUnitGroup(Object... rules) {
for (Object rule : rules) {
addRule(rule);
}
}
@Override
public int getPriority() {
return 0;
}
}
@Rule(name = "既不被2整除也不被3整除")
public class OtherRule {
@Condition
public boolean isOther(@Fact("num") int num){
System.out.println("---isOther----run----");
return num % 2 != 0 && num % 3 != 0;
}
@Action
public void action(@Fact("num") int num){
System.out.print(num);
}
@Priority
public int getPriority(){
return 3;
}
}
复制代码
测试类
public class RuleTest {
public static void main(String[] args) {
RulesEngine rulesEngine = new DefaultRulesEngine();
//创建规则
Rules rules = new Rules();
rules.register(new TwoRule());
rules.register(new ThreeRule());
rules.register(new TwoThreeRuleUnitGroup(new TwoRule(), new ThreeRule()));
rules.register(new OtherRule());
//设置真实数据
Facts facts = new Facts();
for (int i=1 ; i<=10 ; i++){
//规则因素,对应的name,要和规则里面的@Fact 一致
facts.put("num", i);
//执行规则
rulesEngine.fire(rules, facts);
System.out.println();
}
}
}
复制代码
MVELRule
public class MVELTestRule {
public static void main(String[] args) {
//规则引擎
RulesEngine rulesEngine = new DefaultRulesEngine();
//规则
MVELRule ageRule = new MVELRule()
.name("my rule")
.description("test demo rule")
.priority(1)
.when("user.age > 18")
.then("map.put('code',200);map.put('msg','success');");
Rules rules = new Rules();
rules.register(ageRule);
Facts facts = new Facts();
User user = new User();
user.setAge(19);
facts.put("user",user);
Map map = new HashMap();
facts.put("map",map);
rulesEngine.fire(rules,facts);
System.out.println(map);
}
}
复制代码
个人感觉这种方式的创建rule比较灵活,rule的所有信息都可以存储到数据库中,可以实时修改数据库中数据进行修改规则。只需要将相关的类设置到facts中即可。
RuleListener
规则监听器
public class MyRuleListener implements RuleListener {
@Override
public boolean beforeEvaluate(Rule rule, Facts facts) {
return true;
}
@Override
public void afterEvaluate(Rule rule, Facts facts, boolean b) {
System.out.println("---MyRuleListener------afterEvaluate-----");
}
@Override
public void beforeExecute(Rule rule, Facts facts) {
System.out.println("---MyRuleListener------beforeExecute-----");
}
@Override
public void onSuccess(Rule rule, Facts facts) {
System.out.println("---MyRuleListener------onSuccess-----");
}
@Override
public void onFailure(Rule rule, Facts facts, Exception e) {
System.out.println("---MyRuleListener------onFailure-----");
}
}
复制代码
beforeEvaluate
该方法在执行@Condition
修饰的方法之前执行。该方法返回false则不执行条件的判断,直接跳过该当前rule。afterEvaluate
该方法在执行@Condition
修饰的方法之后执行。beforeExecute
该方法在执行@Action
修饰的方法之前执行。onSuccess
该方法在执行@Action
修饰的方法之后执行。onFailure
在执行@Action
修饰的方法出现异常时,该方法执行。
在rulesEngine.fire(rules, facts);
之前注册规则监听器
((DefaultRulesEngine) rulesEngine).registerRuleListener(new MyRuleListener());
复制代码
RulesEngineListener
public class MyRulesEngineListener implements RulesEngineListener {
@Override
public void beforeEvaluate(Rules rules, Facts facts) {
System.out.println("---MyRulesEngineListener------beforeEvaluate-----");
}
@Override
public void afterExecute(Rules rules, Facts facts) {
System.out.println("---MyRulesEngineListener------afterExecute-----");
}
}
复制代码
beforeEvaluate
该方法在执行@Action
修饰的方法之后执行。在RuleListener之前执行afterExecute
该方法在执行@Condition
修饰的方法之前执行。在RuleListener之后执行
在rulesEngine.fire(rules, facts);
之前注册规则引擎监听器
((DefaultRulesEngine) rulesEngine).registerRulesEngineListener(new MyRulesEngineListener());
复制代码
规则引擎初始化参数
- skipOnFirstAppliedRule 为true时, 从第一条开始,匹配一条就会跳过后面规则匹配,不匹配则一直往下执行
- skipOnFirstFailedRule 为true时, 如果执行@Action中发生异常就会跳过后面规则匹配
- skipOnFirstNonTriggeredRule 为true时,从第一条开始,匹配一条才会往下执行,不匹配则跳过后面
- rulePriorityThreshold 大于指定的优先级则不进行匹配
RulesEngineParameters parameters = new RulesEngineParameters()
parameters.skipOnFirstAppliedRule(true);
parameters.skipOnFirstFailedRule(true);
parameters.skipOnFirstNonTriggeredRule(true);
parameters.priorityThreshold(3);
RulesEngine rulesEngine = new DefaultRulesEngine(parameters);
复制代码
多条配置可以一起使用。