先来简单认识下easy-rule中一些核心接口和类。
Rule
规则的接口规范
default String getName() {
return DEFAULT_NAME; // 规则的名称,在同一个规则引擎下名字必须唯一
}
default String getDescription() {
return DEFAULT_DESCRIPTION; // 规则的描述
}
default int getPriority() {
return DEFAULT_PRIORITY; // 规则的优先级 默认int最大值减一
}
boolean evaluate(Facts facts); // 条件判定,达到什么条件时执行 execute
void execute(Facts facts) throws Exception; // 符合规则时需要执行的方法
Rules
用来存放Rule的集合,使用TreeSet集合来存放
因此如果Rule没有定义优先级,则按照Rule 添加的属性进行执行
在往Rules里注册Rule时,根据注册的Rule类型,决定是否使用动态代理+注解解析将注册的对象转为Rule对象
Fact
事实,有个name属性,和T 任意对象的值。比如 name:age 值 :int
Facts
事实集合,使用hashset进行存储,提供put,add,remove,get等基础增删查方法
RulesEngine接口
public interface RulesEngine {
/**
* 获取规则引擎的参数
*/
RulesEngineParameters getParameters();
/**
* 获取规则引擎的所有规则监听器
*/
default List<RuleListener> getRuleListeners() {
return Collections.emptyList();
}
/**
* 获取规则引擎的监听器
*/
default List<RulesEngineListener> getRulesEngineListeners() {
return Collections.emptyList();
}
/**
* 规则引擎符合条件时触发的方法
*/
void fire(Rules rules, Facts facts);
/**
* 检查规则引擎的每个规则的条件是否满足,只检查,即使满足也不做触发时的逻辑
*/
default Map<Rule, Boolean> check(Rules rules, Facts facts) {
return Collections.emptyMap();
}
}
AbstractRulesEngin
实现自RulesEngine接口,额外提供了三个成员变量
RulesEngineParameters parameters;// 规则引擎参数
List<RuleListener> ruleListeners; // 规则的监听器,rule的生命周期函数 6个
List<RulesEngineListener> rulesEngineListeners;// 规则引擎的监听器 相当于rules的生命周期函数,2
额外提供注册ruleListener和rulesEngineListener的方法
RulesEngineParameter
规则引擎参数,提供四个成员变量
/**
* 当有一个规则执行成功跳过接下来的rule
*/
private boolean skipOnFirstAppliedRule;
/**
* 当有一个规则没有触发,跳过接下来的规则
*/
private boolean skipOnFirstNonTriggeredRule;
/**
* 当有一个规则执行失败了 跳过接来的规则
*/
private boolean skipOnFirstFailedRule;
/**
* 如果定义的优先级超出这个阈值 那么就跳过
*/
private int priorityThreshold;
DefaultRulesEngine
默认规则引擎,继承自AbstractRulesEngine,根据自然的顺序执行。遍历所有的规则,当条件触发时执行action.
在此类中使用parameter,parameter参数会被应用于所有的规则
程序入口:
fire(Rules rules, Facts facts)
调用fire方法后会先执行规则引擎的第一个生命周期函数,即RulesEngineListener.beforeEvaluate(Rules rules, Facts facts)
执行完成之后会执行规则引擎的最后一个生命周期函数,即RulesEngineListener.afterExecute(Rules rules, Facts facts),
doFire方法
doFire(Rules rules, Facts facts)方法
遍历Rules集合执行如下动作:
-
检查优先级是否超阈值,如果超出,直接退出本次规则引擎的执行
-
调用Rule的第一个生命周期函数beforeEvaluate,即校验该规则是否需要被判断执行
-
调用Rule的evaluate方法,判断是否符合定义的规则
- 如果执行成功,且调用结果为 true,即符合定义的规则
- 那么执行Rule的afterEvaluate和,triggerListenersBeforeExecute,然后执行execute动作,exec成功,则执行onSuccess周期函数
- 执行失败则调用onFailre周期函数
- 如果执行成功,且调用结果为false,执行Rule的afterEvaluate,按需执行parameter的isSkipOnFirstNonTriggeredRule
- 如果执行失败,则执行triggerListenersOnEvaluationError函数
- 如果执行成功,且调用结果为 true,即符合定义的规则
InferenceRulesEngine
推理规则引擎,继承自AbstractRulesEngine,与默认规则引擎的区别是:
DefaultRulesEngine默认规则引擎会遍历所有的规则,然后执行上述1,2,3步骤,而InferenceRulesEngine一直从Rules挑选出符合判定条件的Rule集合,然后调用DefaultRulesEngine的fire方法。直到Rules中没有符合条件的为止。
InferenceRulesEngine类唯一的成员变量
private final DefaultRulesEngine delegate;
使用默认规则引擎作为代,挑选出需要执行的Rules,交给DefaultRulesEngine进行fire
使用do while循环,不断的挑选符合条件的规则,进行执行
代码举例
DefaultRulesEngine
package com.shemuel.easyrule;
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 = "weather rule", description = "if it rains then take an umbrella")
public class WeatherRule {
@Condition
public boolean itRains(@Fact("rain") Integer rain) {
return rain == 1;
}
@Action
public void takeAnUmbrella() {
System.out.