前言
这一章简单介绍一下此组件的使用方式,当然,在其github首页也有介绍,不过不是很全面,所以在此稍作补充。
Maven引用
<!--easy rules核心库-->
<dependency>
<groupId>org.jeasy</groupId>
<artifactId>easy-rules-core</artifactId>
<version>4.1.0</version>
</dependency>
<!--规则定义文件格式,支持json,yaml等-->
<dependency>
<groupId>org.jeasy</groupId>
<artifactId>easy-rules-support</artifactId>
<version>4.1.0</version>
</dependency>
<!--支持mvel规则语法库-->
<dependency>
<groupId>org.jeasy</groupId>
<artifactId>easy-rules-mvel</artifactId>
<version>4.1.0</version>
</dependency>
创建规则
priority属性一定要设置,否则默认为2147483646,如果设定了阈值,则业务规则不会被触发,需要特别注意。
注解方式
主要有三个注解【@Rule】、【@Condition】、【@Action】,其中action注解有order顺序设置,可以根据业务需求,预设执行顺序。
@Rule(name = "test-1", priority = 9,description = "注解规则测试")
public class MyRule {
/**
* 条件
* @return 是否满足触发条件
*/
@Condition
public boolean when(@Fact("age") int age) {
System.out.println("执行第一个条件。");
return age > 19;
}
@Action(order = 2)
public void execBiz1() {
System.out.println("执行第一个业务。");
}
@Action(order = 1)
public void execBiz2() {
System.out.println("执行第二个业务。");
}
}
注意,只能有一个条件,否则报错:
Rule 'com.netease.ot.job.MyRule' must have exactly one method annotated with 'org.jeasy.rules.annotation.Condition'
如果返回false,则输出日志:Rule 'test-1' has been evaluated to false, it has not been executed
Builder方式
// builder创建规则
Rule codeRule = new RuleBuilder()
.name("builder-rule")
.description("这是Builder规则")
.priority(5)
.when(factSet -> (int) factSet.get("age") > 18)
.then(factSet -> System.out.println("builder rule 被触发1,年龄大于18."))
.then(factSet -> System.out.println("builder rule 被触发2,年龄大于18."))
.build();
表达式
// 表达式规则
Rule elRule = new MVELRule()
.name("el-rule")
.priority(8)
.description("这是表达式规则")
.when("age > 15")
.then("System.out.println("el rule 被触发,年龄大于15.");");
监听器
规则
这里需要注意的只有beforeEvaluate事件,这个方法返回值为false,其结果决定了规则是否可以评估通过,如果返回false,afterEvaluate监听事件也不会被执行。
public class MyRuleListener implements RuleListener {
@Override
public boolean beforeEvaluate(Rule rule, Facts facts) {
System.out.println("规则评估前触发");
// 注意这个返回值,也决定了规则是否可以评估通过,如果返回false,afterEvaluate监听事件也不会被执行
return (int) facts.get("age") > 10;
}
@Override
public void afterEvaluate(Rule rule, Facts facts, boolean evaluationResult) {
System.out.println("规则评估后触发,评估是否通过:" + evaluationResult);
}
@Override
public void onEvaluationError(Rule rule, Facts facts, Exception exception) {
System.out.println("规则评估失败触发");
}
@Override
public void beforeExecute(Rule rule, Facts facts) {
System.out.println("规则执行前触发");
}
@Override
public void onSuccess(Rule rule, Facts facts) {
System.out.println("规则成功后触发");
}
@Override
public void onFailure(Rule rule, Facts facts, Exception exception) {
System.out.println("规则失败后触发");
}
}
引擎
与规则监听器相比,引擎监听器则无需注意什么了,可以当成是引擎的一个截面,输出日志或者进行特殊业务调整。比如在监听器里进行规则评估,通知相关利益人满足条件的规则;或者动态添加事实或者规则,用来应对突发情况。
public class MyRulesEngineListener implements RulesEngineListener {
@Override
public void beforeEvaluate(Rules rules, Facts facts) {
System.out.println("引擎监听,评估前触发。");
}
@Override
public void afterExecute(Rules rules, Facts facts) {
System.out.println("引擎监听,执行后触发。");
}
}
例子
// 创建因子
Facts facts = new Facts();
facts.add(new Fact<>("age", 28));
// 规则集合
Rules rules = new Rules();
// 添加注解规则
rules.register(new MyRule());
rules.register(new TestRule());
// builder创建规则
Rule codeRule = new RuleBuilder()
.name("builder-rule")
.description("这是代码规则")
.priority(5)
.when(factSet -> (int) factSet.get("age") > 18)
.then(factSet -> System.out.println("builder rule 被触发1,年龄大于18."))
.then(factSet -> System.out.println("builder rule 被触发2,年龄大于18."))
.build();
rules.register(codeRule);
// 表达式规则
Rule elRule = new MVELRule()
.name("el-rule")
.priority(9)
.description("这是表达式规则")
.when("age > 15")
.then("System.out.println("el rule 被触发,年龄大于15.");");
rules.register(elRule);
// 创建引擎参数
RulesEngineParameters parameters = new RulesEngineParameters()
// 告诉引擎如果优先级超过定义的阈值,则跳过下一个规则
.priorityThreshold(10)
// 当一个规则触发之后,是否跳过之后所有的规则
.skipOnFirstAppliedRule(false)
// 当一个规则失败之后,是否跳过之后所有的规则
.skipOnFirstFailedRule(true)
// 当第一个规则没有触发,是否跳过之后所有的规则
.skipOnFirstNonTriggeredRule(false);
// 创建引擎
DefaultRulesEngine defaultEngine = new DefaultRulesEngine(parameters);
defaultEngine.registerRuleListener(new MyRuleListener());
defaultEngine.registerRulesEngineListener(new MyRulesEngineListener());
defaultEngine.fire(rules, facts);
输出
引擎监听,评估前触发。
17:14:08.265 [main] DEBUG org.jeasy.rules.core.DefaultRulesEngine - Engine parameters { skipOnFirstAppliedRule = false, skipOnFirstNonTriggeredRule = false, skipOnFirstFailedRule = true, priorityThreshold = 10 }
17:14:08.269 [main] DEBUG org.jeasy.rules.core.DefaultRulesEngine - Registered rules:
17:14:08.274 [main] DEBUG org.jeasy.rules.core.DefaultRulesEngine - Rule { name = 'test-2', description = 'when when then execBiz2', priority = '2'}
17:14:08.274 [main] DEBUG org.jeasy.rules.core.DefaultRulesEngine - Rule { name = 'builder-rule', description = '这是代码规则', priority = '5'}
17:14:08.274 [main] DEBUG org.jeasy.rules.core.DefaultRulesEngine - Rule { name = 'el-rule', description = '这是表达式规则', priority = '9'}
17:14:08.274 [main] DEBUG org.jeasy.rules.core.DefaultRulesEngine - Rule { name = 'test-1', description = '注解规则测试', priority = '9'}
17:14:08.275 [main] DEBUG org.jeasy.rules.core.DefaultRulesEngine - Known facts:
17:14:08.275 [main] DEBUG org.jeasy.rules.core.DefaultRulesEngine - Fact{name='age', value=28}
17:14:08.275 [main] DEBUG org.jeasy.rules.core.DefaultRulesEngine - Rules evaluation started
规则评估前触发
17:14:08.282 [main] WARN org.jeasy.rules.core.RuleProxy - Rule 'com.netease.ot.job.TestRule' has been evaluated to false due to a declared but missing fact 'rain' in [Fact{name='age', value=28}]
17:14:08.282 [main] DEBUG org.jeasy.rules.core.DefaultRulesEngine - Rule 'test-2' has been evaluated to false, it has not been executed
规则评估后触发,评估是否通过:false
规则评估前触发
17:14:08.285 [main] DEBUG org.jeasy.rules.core.DefaultRulesEngine - Rule 'builder-rule' triggered
规则评估后触发,评估是否通过:true
规则执行前触发
builder rule 被触发1,年龄大于18.
builder rule 被触发2,年龄大于18.
17:14:08.285 [main] DEBUG org.jeasy.rules.core.DefaultRulesEngine - Rule 'builder-rule' performed successfully
规则成功后触发
规则评估前触发
17:14:08.318 [main] DEBUG org.jeasy.rules.core.DefaultRulesEngine - Rule 'el-rule' triggered
规则评估后触发,评估是否通过:true
规则执行前触发
el rule 被触发,年龄大于15.
17:14:08.326 [main] DEBUG org.jeasy.rules.core.DefaultRulesEngine - Rule 'el-rule' performed successfully
规则成功后触发
规则评估前触发
执行第一个条件。
17:14:08.327 [main] DEBUG org.jeasy.rules.core.DefaultRulesEngine - Rule 'test-1' triggered
规则评估后触发,评估是否通过:true
规则执行前触发
执行第二个业务。
执行第一个业务。
17:14:08.327 [main] DEBUG org.jeasy.rules.core.DefaultRulesEngine - Rule 'test-1' performed successfully
规则成功后触发
引擎监听,执行后触发。