最近在思考一个基于规则进行挑选的技术重构,想通过规则引擎进行实现,借着这个机会正好可以详细了解一下规则引擎。本篇文章将会详细介绍规则引擎easy-rules的使用。
Easy Rules是一个简单但功能强大的Java规则引擎,提供以下特性:
- 轻量级框架和易于学习的API
- 基于POJO的开发
- 支持从原始规则创建组合规则
- 支持通过表达式(如MVEL,SPEL和JEXL)定义规则
开始使用
引入依赖
<dependency>
<groupId>org.jeasy</groupId>
<artifactId>easy-rules-core</artifactId>
<version>4.1.0</version>
</dependency>
复制代码
上面只引入了core模块依赖,如需要其它模块内容,再引入对应依赖即可。
定义规则
介绍
大多数业务规则可以用以下定义表示:
- name:规则命名空间中的唯一规则名称
- description:规则的简要描述
- priority:规则的优先级
- facts:触发规则时的一组已知事实
- conditions:在给定一些事实的情况下,为了应用该规则,需要满足的一组条件
- actions:满足条件时要执行的一组操作(可能会添加/删除/修改事实)
Easy Rules为定义业务规则的每个关键点提供了抽象。Easy Rules中的规则由Rule
接口表示:
public interface Rule extends Comparable<Rule> {
/**
* 此方法封装了规则的条件。
* @return 如果根据提供的事实可以应用规则,则为true,否则为false
*/
boolean evaluate(Facts facts);
/**
* 此方法封装了规则的操作。
* @throws 如果在执行操作期间发生错误,则抛出异常
*/
void execute(Facts facts) throws Exception;
//Getters and setters for rule name, description and priority omitted.
}
复制代码
evaluate()
方法封装了必须为true
才能触发规则的条件。execute()
方法封装了在满足规则条件时应该执行的操作。条件和操作由Condition
和Action
接口表示。
规则可以用两种不同的方式定义:
- 通过在
POJO
上添加注解来声明 - 通过
RuleBuilder
API编程
这些是定义规则的最常用方法,但是如果需要,您也可以实现Rule
接口或扩展BasicRule
类。
使用注解定义规则
Easy Rules提供了@Rule
注解,可以将POJO转换为规则。
@Rule(name = "my rule", description = "my rule description", priority = 1)
public class MyRule {
@Condition
public boolean when(@Fact("fact") fact) {
// 规则条件
return true;
}
@Action(order = 1)
public void then(Facts facts) throws Exception {
// 规则为true时的操作1
}
@Action(order = 2)
public void finally() throws Exception {
// 规则为true时的操作2
}
}
复制代码
@Condition
注解用来标记评估规则条件的方法,这个方法必须是public
,可以有一个或多个带@Fact
注解的参数,并返回一个boolean
类型。只有一个方法可以用@Condition
注解标记。
@Action
注解用来标记执行操作的方法,规则可以有多个操作。可以使用order
属性以指定的顺序执行操作。
使用RuleBuilder
定义规则
RuleBuilder
允许你用流式API定义规则。
Rule rule = new RuleBuilder()
.name("myRule")
.description("myRuleDescription")
.priority(3)
.when(condition)
.then(action1)
.then(action2)
.build();
复制代码
在本例中,condition
是Condition
接口的实例,action1
和action2
是Action
接口的实例。
组合规则
Easy Rules允许从原始规则创建复杂的规则。一个CompositeRule
由一组规则组成。组合规则是一个抽象概念,因为组合规则可以以不同的方式触发。Easy Rules提供了3种Compos