运行环境
Easy Rules是一个Java库, 需要运行在Java 1.7及以上。
maven依赖
<!--easy rules核心库-->
<dependency>
<groupId>org.jeasy</groupId>
<artifactId>easy-rules-core</artifactId>
<version>4.0.0</version>
</dependency>
<!--规则定义文件格式,支持json,yaml等-->
<dependency>
<groupId>org.jeasy</groupId>
<artifactId>easy-rules-mvel</artifactId>
<version>4.0.0</version>
</dependency>
<!--支持mvel规则语法库-->
<dependency>
<groupId>org.jeasy</groupId>
<artifactId>easy-rules-spel</artifactId>
<version>4.0.0</version>
</dependency>
定义规则
- name:规则命名空间中的唯一规则名称
- description:规则的简要描述
- priority:规则的优先级
- facts:触发规则时的一组已知事实
- conditions:在给定一些事实的情况下,为了应用该规则,需要满足的一组条件
- actions:满足条件时要执行的一组操作(可能会添加/删除/修改事实)
规则定义,方式有很多种:
方式一:注解
@Rule(name = "weather rule", description = "if it rains then take an umbrella")
public class WeatherRule {
@Condition
public boolean itRains(@Fact("rain") boolean rain) {
return rain;
}
@Action
public void takeAnUmbrella() {
System.out.println("It rains, take an umbrella!");
}
}
方式二:链式编程
Rule weatherRule = new RuleBuilder()
.name("weather rule")
.description("if it rains then take an umbrella")
.when(facts -> facts.get("rain").equals(true))
.then(facts -> System.out.println("It rains, take an umbrella!"))
.build();
方式三:表达式
Rule weatherRule = new MVELRule()
.name("weather rule")
.description("if it rains then take an umbrella")
.when("rain == true")
.then("System.out.println(\"It rains, take an umbrella!\");");
方式四:yml或json配置文件
name: "weather rule"
description: "if it rains then take an umbrella"
condition: "rain == true"
actions:
- "System.out.println(\"It rains, take an umbrella!\");"
方式五:组合规则
CompositeRule由一组规则组成。这是一个典型地组合设计模式的实现。
组合规则是一个抽象概念,因为可以以不同方式触发组合规则。
Easy Rules自带三种CompositeRule实现:
UnitRuleGroup : 要么应用所有规则,要么不应用任何规则(AND逻辑)
ActivationRuleGroup : 它触发第一个适用规则,并忽略组中的其他规则(XOR逻辑)
ConditionalRuleGroup : 如果具有最高优先级的规则计算结果为true,则触发其余规则
复合规则可以从基本规则创建并注册为常规规则:
//Create a composite rule from two primitive rules
UnitRuleGroup myUnitRuleGroup = new UnitRuleGroup("myUnitRuleGroup", "unit of myRule1 and myRule2");
myUnitRuleGroup.addRule(myRule1);
myUnitRuleGroup.addRule(myRule2);
//Register the composite rule as a regular rule
Rules rules = new Rules();
rules.register(myUnitRuleGroup);
RulesEngine rulesEngine = new DefaultRulesEngine();
rulesEngine.fire(rules, someFacts);
每个规则都有优先级。它代表触发注册规则的默认顺序。默认情况下,较低的值表示较高的优先级。可以重写compareTo方法以提供自定义优先级策略。
定义引擎规则
从版本3.1开始,Easy Rules提供了RulesEngine接口的两种实现:
DefaultRulesEngine:根据规则的自然顺序(默认为优先级)应用规则。
InferenceRulesEngine:持续对已知事实应用规则,直到不再应用规则为止。
创建一个规则引擎
要创建规则引擎,可以使用每个实现的构造函数:
RulesEngine rulesEngine = new DefaultRulesEngine();
// or
RulesEngine rulesEngine = new InferenceRulesEngine();
然后,您可以按以下方式触发注册规则:
rulesEngine.fire(rules, facts);
规则引擎参数
asy Rules 引擎可以配置以下参数:
Parameter | Type | Required | Default |
---|---|---|---|
rulePriorityThreshold | int | no | MaxInt |
skipOnFirstAppliedRule | boolean | no | false |
skipOnFirstFailedRule | boolean | no | false |
skipOnFirstNonTriggeredRule | boolean | no | false |
- skipOnFirstAppliedRule:告诉引擎规则被触发时跳过后面的规则。
- skipOnFirstFailedRule:告诉引擎在规则失败时跳过后面的规则。
- skipOnFirstNonTriggeredRule:告诉引擎一个规则不会被触发跳过后面的规则。
- rulePriorityThreshold:告诉引擎如果优先级超过定义的阈值,则跳过下一个规则。版本3.3已经不支持更改,默认MaxInt。
- 在规则文件中,不同的规则也可以设置相同的优先级,这是语法允许的。
- 在创建规则引擎并为其设置属性时,可以同时设置多个,可以使用RulesEngineParameters API指定这些参数:
RulesEngineParameters parameters = new RulesEngineParameters()
.rulePriorityThreshold(10)
.skipOnFirstAppliedRule(true)
.skipOnFirstFailedRule(true)
.skipOnFirstNonTriggeredRule(true);
RulesEngine rulesEngine = new DefaultRulesEngine(parameters);
- 在设置了规则引擎的属性后,在程序接下来的某个阶段如果需要改变该引擎的属性,可以先得到该引擎的属性,然后再重新设置属性值。如果要从引擎获取参数,可以使用以下代码段:
RulesEngineParameters parameters = myEngine.getParameters();
这允许您在创建引擎后重置引擎参数。
应用规则
public class Test {
public static void main(String[] args) {
// 定义数据
Facts facts = new Facts();
facts.put("rain", true);
// 注册
Rules rules = new Rules();
rules.register(weatherRule);
// 启动点火
RulesEngine rulesEngine = new DefaultRulesEngine();
rulesEngine.fire(rules, facts);
}
}
入门案例:Hello Easy Rules
依赖引入
在pom.xml引入依赖
<dependency>
<groupId>org.jeasy</groupId>
<artifactId>easy-rules-core</artifactId>
<version>4.0.0</version>
</dependency>
生成一个HelloWorldRule规则
package com.ronwe.linfusecloud.util.testeasyrule;
import org.jeasy.rules.annotation.Action;
import org.jeasy.rules.annotation.Condition;
import org.jeasy.rules.annotation.Rule;
@Rule(name = "Hello World rule", description = "Always say hello world")
public class HelloWorldRule {
@Condition
public boolean when() {
return true;
}
@Action
public void then() throws Exception {
System.out.println("hello world");
}
}
编写main函数,启动测试
package com.ronwe.linfusecloud.util.testeasyrule;
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 HelloWorldRuleClient {
public static void main(String[] args) throws Exception {
// 定义数据
Facts facts=new Facts();
// 注册
Rules rules=new Rules();
rules.register(new HelloWorldRule());
//启动点火
RulesEngine rulesEngine=new DefaultRulesEngine();
rulesEngine.fire(rules,facts);
}
}
测试结果
学习文档: