DefaultRulesEngine rulesEngine = new DefaultRulesEngine();
rulesEngine.registerRuleListener(); rulesEngine.registerRulesEngineListener();
在EasyRule中注册监听器偶然发现有这两个方法,那他们到底有什么区别呢?
根据官方文档的描述来看
Unlike the RuleListener that is executed for each rule, the RulesEngineListener allows you to provide custom behavior before/after firing the entire rule set. To register your listener, use the following snippet:
翻译:与为每个规则执行的RuleListener不同,RulesEngineListener允许您在触发整个规则集之前之后提供自定义行为。
也就是说RuleEngineListener它适合用于规则组的一个前置和后置触发,而规则集包含以下几种
UnitRuleGroup:单元规则组是作为一个单元的复合规则:要么应用所有规则,要么什么都不应用。
ActivationRuleGroup:激活规则组是一个复合规则,它触发第一个适用规则,并忽略组中的其他规则(XOR逻辑)。规则首先按照组内的自然顺序(默认优先级)进行排序。
ConditionalRuleGroup:条件规则组是一个复合规则,其中优先级最高的规则充当条件:如果优先级最高的规则求值为true,则触发其余规则。
这里的用词是适用于,而不是必须用在规则组,当然单个Rules规则也是可以的(单个规则我感觉没有太大意义)
而RuleEngineListener只提供了以下两个方法
其实从源码上来看更好理解:
执行规则判断的核心方法就是fire方法
执行fire方法后会去执行triggerListenersBeforeRules方法
可以看到这个方法是会调用RuleEngineListener的监听器
如果我们在注册监听器的时候是调用registerRulesEngineListener,那么就会往List<RulesEngineListener>进行添加,所以rulesEngineListeners就会去foreach我们自定义实现的RuleEngineListener的beforeEvalute方法,反之如果是调用的是registerRulesListener,那么这里就不会执行
那么什么时候执行RuleListener的方法呢,核心就在doFire方法中
void doFire(Rules rules, Facts facts) {
if (rules.isEmpty()) {
LOGGER.warn("No rules registered! Nothing to apply");
return;
}
logEngineParameters();
log(rules);
log(facts);
LOGGER.debug("Rules evaluation started");
for (Rule rule : rules) {
final String name = rule.getName();
final int priority = rule.getPriority();
if (priority > parameters.getPriorityThreshold()) {
LOGGER.debug("Rule priority threshold ({}) exceeded at rule '{}' with priority={}, next rules will be skipped",
parameters.getPriorityThreshold(), name, priority);
break;
}
//这里执行RuleListener的beforeEvaluate,如果此方法返回false就不会执行后面的逻辑
if (!shouldBeEvaluated(rule, facts)) {
LOGGER.debug("Rule '{}' has been skipped before being evaluated", name);
continue;
}
boolean evaluationResult = false;
try {
//这里执行规则判断,也就是when里面的逻辑,规则判断成功返回true
evaluationResult = rule.evaluate(facts);
} catch (RuntimeException exception) {
LOGGER.error("Rule '" + name + "' evaluated with error", exception);
triggerListenersOnEvaluationError(rule, facts, exception);
// give the option to either skip next rules on evaluation error or continue by considering the evaluation error as false
if (parameters.isSkipOnFirstNonTriggeredRule()) {
LOGGER.debug("Next rules will be skipped since parameter skipOnFirstNonTriggeredRule is set");
break;
}
}
if (evaluationResult) {
LOGGER.debug("Rule '{}' triggered", name);
//这里执行RuleListener的afterEvaluate方法
triggerListenersAfterEvaluate(rule, facts, true);
try {
//这里执行RuleListener的BeforeExecute方法
triggerListenersBeforeExecute(rule, facts);
//这里执行then的逻辑
rule.execute(facts);
LOGGER.debug("Rule '{}' performed successfully", name);
//这里执行RuleListener的onSuccess的逻辑
triggerListenersOnSuccess(rule, facts);
if (parameters.isSkipOnFirstAppliedRule()) {
LOGGER.debug("Next rules will be skipped since parameter skipOnFirstAppliedRule is set");
break;
}
} catch (Exception exception) {
LOGGER.error("Rule '" + name + "' performed with error", exception);
triggerListenersOnFailure(rule, exception, facts);
if (parameters.isSkipOnFirstFailedRule()) {
LOGGER.debug("Next rules will be skipped since parameter skipOnFirstFailedRule is set");
break;
}
}
} else {
LOGGER.debug("Rule '{}' has been evaluated to false, it has not been executed", name);
triggerListenersAfterEvaluate(rule, facts, false);
if (parameters.isSkipOnFirstNonTriggeredRule()) {
LOGGER.debug("Next rules will be skipped since parameter skipOnFirstNonTriggeredRule is set");
break;
}
}
}
}
来一张图更好理解
如果同时两个监听器都注册,那么它的执行顺序如下:
(1)RuleEngineListener的beforeEvaluate()
(2)RuleListener的beforeEvaluate()
(3)RuleListener的afterEvaluate()
(4)RuleListener的beforeExecute()
(5)RuleListener的OnSuccess()
(6)RuleEngineListener的afterExecute()
总结:其实不管单个规则还是组合规则,只要实现监听器都会去触发对应监听器的方法,从我的理解来看,RuleListener着重的是对规则生命周期的一个监听,RuleEngineListener着重的是对执行规则集前后的一个准备