网站首页 > 博客文章 正文
场景
简单点描述,有点策略模式的味道,所以可以处理if...else...语句;
其核心内容还是在规则引擎,所以和Drools规则类似,目前支持MVEL和SpEL表达式,配置外置;
最后支持各种规则的组合,支持OR和AND等多种规则组合模式。
1、支持facts作为参数判断,解放if...else...语句;
3、支持规则文件外置,释放研发生产力;
2、支持规则组合,实现多业务规则链路执行,短路执行。
功能
- 轻量级框架,基于API方式
- 支持基于POJO和注解方式开发
- 支持创建组合规则
- 支持使用表达式语言(MVEL/SpEL)
名词描述
- name:规则名称,唯一性
- description:说明描述
- priority:优先级
- Facts:事实
- Conditions:条件
- Actions:执行动作
案例
背景
定义一个业务订单的场景,根据订单类型,执行对应的业务操作。假设,订单类型为两种:普通类型、折扣类型。
普通类型订单:打印日志处理
折扣类型订单:执行折扣计算方法
maven依赖
<dependency>
<groupId>org.jeasy</groupId>
<artifactId>easy-rules-core</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>org.jeasy</groupId>
<artifactId>easy-rules-mvel</artifactId>
<version>4.0.0</version>
</dependency>
<dependency>
<groupId>org.jeasy</groupId>
<artifactId>easy-rules-spel</artifactId>
<version>4.0.0</version>
</dependency>
订单对象
@Data
public class BizOrder {
/**
* 商品
*/
private String goods;
/**
* 售价
*/
private BigDecimal amount;
/**
* 订单类型 1、普通类型 2、折扣类型
*/
private Integer type;
/**
* 折扣
*/
private BigDecimal discount;
}
折扣计算
@Component
@Slf4j
public class OrderService {
/**
* 折扣处理方法
* @param param 参数
*/
public static void doDiscountAction(Object param) {
if (param instanceof BizOrder) {
BizOrder order = ((BizOrder) param);
log.error("商品goods:{},折后amount:{}",
order.getGoods(), order.getAmount().multiply(order.getDiscount()));
}
}
}
实现方式
1、基于表达式
步骤
- 定义事实数据
//定义事实数据
Facts facts = new Facts();
facts.put("type", order.getType());
设置订单类型作为参数。
源码分析
public interface Rule extends Comparable<Rule> {
String DEFAULT_NAME = "rule";
String DEFAULT_DESCRIPTION = "description";
int DEFAULT_PRIORITY = Integer.MAX_VALUE - 1;
default String getName() {
return DEFAULT_NAME;
}
default String getDescription() {
return DEFAULT_DESCRIPTION;
}
default int getPriority() {
return DEFAULT_PRIORITY;
}
boolean evaluate(Facts facts);
void execute(Facts facts) throws Exception;
实现了Iterable接口,含有一个Set集合的容器。
- 表达式分别定义普通类型、折扣类型规则Rule。
Rule ordinaryRule = new RuleBuilder()
.name("ordinary_order_rule")
.description("普通订单类型")
.when(vo -> vo.get("type").equals(1))
.then(vo -> log.info("这是一个普通订单"))
.build();
源码分析
public interface Rule extends Comparable<Rule> {
String DEFAULT_NAME = "rule";
String DEFAULT_DESCRIPTION = "description";
int DEFAULT_PRIORITY = Integer.MAX_VALUE - 1;
default String getName() {
return DEFAULT_NAME;
}
default String getDescription() {
return DEFAULT_DESCRIPTION;
}
default int getPriority() {
return DEFAULT_PRIORITY;
}
boolean evaluate(Facts facts);
void execute(Facts facts) throws Exception;
很明显是Comparable的一个子类,方法evaluate()返回boolean是否加载了规则,以及execute()执行规则动作。
- 注册规则
//注册
Rules rules = new Rules();
rules.register(activationRuleGroup);
- 启动点火
//启动点火
RulesEngine rulesEngine = new DefaultRulesEngine();
rulesEngine.fire(rules, facts);
采用了默认的规则引擎
整体代码实现
@AuthIgnore
@OperationLog(value = "easy rules 表达式测试")
@PostMapping("/stream")
@SneakyThrows
public ResultVo<?> streamTest(@RequestBody BizOrder order) {
//定义事实数据
Facts facts = new Facts();
facts.put("type", order.getType());
ActivationRuleGroup activationRuleGroup = new ActivationRuleGroup("order_type_rule","订单类型规则");
//普通类型
Rule ordinaryRule = new RuleBuilder()
.name("ordinary_order_rule")
.description("普通订单类型")
.when(vo -> vo.get("type").equals(1))
.then(vo -> log.info("这是一个普通订单"))
.build();
activationRuleGroup.addRule(ordinaryRule);
//折扣类型
Rule discountRule = new RuleBuilder()
.name("discount_order_rule")
.description("折扣订单类型")
.when(vo -> vo.get("type").equals(2))
.then(vo -> {
log.info("这是一个折扣订单");
//执行其他逻辑
OrderService.doDiscountAction(order);
})
.build();
activationRuleGroup.addRule(discountRule);
//注册
Rules rules = new Rules();
rules.register(activationRuleGroup);
//启动点火
RulesEngine rulesEngine = new DefaultRulesEngine();
rulesEngine.fire(rules, facts);
return ResultVo.success();
}
调试
请求参数
输出日志
我们也可以从日志中看出规则引擎加载的参数,规则注册,以及facts的赋值,
2、基于注解
分别定义两个规则POJO
普通类型订单
@Rule(name = "ordinary_order_rule", description = "普通订单类型", priority = 1)
@Slf4j
public class OrdinaryOrderRule {
@Condition
public boolean when(@Fact("order") BizOrder order) {
return Objects.equals(order.getType(), 1);
}
@Action
public void action(@Fact("order") BizOrder order) {
log.info("这是一个普通订单,商品goods:{}", order.getGoods());
}
}
折扣类型订单
@Rule(name = "discount_order_rule", description = "折扣订单类型",priority =2)
@Slf4j
public class DiscountOrderRule {
@Condition
public boolean when(@Fact("order")BizOrder order) {
return Objects.equals(order.getType(),2);
}
@Action(order = 1)
public void action(@Fact("order")BizOrder order) {
log.info("这是一个折扣订单,商品goods:{}",order.getGoods());
}
@Action(order = 2)
public void action2(@Fact("order")BizOrder order) {
//调用其他业务处理
OrderService.doDiscountAction(order);
}
}
接口处理
@AuthIgnore
@OperationLog(value = "easy rules 注解测试")
@PostMapping("/annotation")
@SneakyThrows
public ResultVo<?> annotationTest(@RequestBody BizOrder order) {
//定义数据
Facts facts = new Facts();
facts.put("order", order);
ActivationRuleGroup activationRuleGroup = new ActivationRuleGroup("order_type_rule","订单类型规则");
activationRuleGroup.addRule(new OrdinaryOrderRule());
activationRuleGroup.addRule(new DiscountOrderRule());
//注册
Rules rules = new Rules();
rules.register(activationRuleGroup);
//启动点火
RulesEngine rulesEngine = new DefaultRulesEngine();
rulesEngine.fire(rules, facts);
return ResultVo.success();
}
3、基于配置文件
可以是json(本文),也可以是yml,当然也可以结合Apollo。
定义json文件,biz_order_rule.json
[
{
"name":"order_type_rule",
"description":"订单类型规则引擎",
"priority":1,
"compositeRuleType":"ActivationRuleGroup",
"composingRules":[
{
"name":"ordinary_order_rule",
"description":"普通订单类型",
"condition":"param.getType().equals(1)",
"priority":1,
"actions":[
"System.out.println(\"这是一个普通订单\")"
]
},
{
"name":"discount_order_rule",
"description":"折扣类型规则",
"condition":"param.getType().equals(2)",
"priority":2,
"actions":[
"OrderService.doDiscountAction(param)"
]
}
]
}
]
构建rules配置
@Component
public class ConfigRules {
/**
* 构建rules配置
*/
public Rules fetchConfigRules() throws Exception {
//JSON 表达式
MVELRuleFactory ruleFactory = new MVELRuleFactory(new JsonRuleDefinitionReader());
return ruleFactory.createRules(new FileReader(
Objects.requireNonNull(SpringBootApplication.class.getClassLoader().getResource("biz_order_rule.json"))
.getFile())
);
}
}
API逻辑处理
@AuthIgnore
@OperationLog(value = "easy rules 配置文件测试")
@PostMapping("/json")
@SneakyThrows
public ResultVo<?> jsonTest(@RequestBody BizOrder order) {
//定义数据
Facts facts = new Facts();
facts.put("param", order);
facts.put("OrderService",OrderService.class);
//读取配置
Rules rules = configRules.fetchConfigRules();
BizRule<BizOrder> rule = new BizRule<>();
//注册
rules.register(rule);
//启动
RulesEngine rulesEngine = new DefaultRulesEngine();
rulesEngine.fire(rules, facts);
return ResultVo.success();
}
参考官方文档:https://github.com/j-easy/easy-rules/wiki
猜你喜欢
- 2024-12-30 IF嵌套层数太多?试试Drools规则引擎
- 2024-12-30 低代码开发重要工具:jvs-logic(逻辑引擎)基础原理与功能架构
- 2024-12-30 Java逻辑引擎服务编排,零代码低成本解决企业复杂业务需求
- 2024-12-30 JVS开源框架系列:多租户管理「含开源地址」
- 2024-12-30 开启灵活开发编码模式:规则引擎drools——基础语法
- 2024-12-30 Aviator规则引擎最佳实践 ilog规则引擎
- 2024-12-30 使用若依框架开发和部署简单应用的基本过程
- 2024-12-30 认识工作流程引擎 认识工作流程引擎教案
- 2024-12-30 开源规则引擎LiteFlow项目应用实践
- 2024-12-30 JAVA工作流「java工作流引擎框架」
你 发表评论:
欢迎- 07-07Xiaomi Enters SUV Market with YU7 Launch, Targeting Tesla with Bold Pricing and High-Tech Features
- 07-07Black Sesame Maps Expansion Into Robotics With New Edge AI Strategy
- 07-07Wuhan's 'Black Tech' Powers China's Cross-Border Push with Niche Electronics and Scientific Firepower
- 07-07Maven 干货 全篇共:28232 字。预计阅读时间:110 分钟。建议收藏!
- 07-07IT运维必会的30个工具(it运维工具软件)
- 07-07开源项目有你需要的吗?(开源项目什么意思)
- 07-07自动化测试早就跑起来了,为什么测试管理还像在走路?
- 07-07Cursor 最强竞争对手来了,专治复杂大项目,免费一个月
- 最近发表
-
- Xiaomi Enters SUV Market with YU7 Launch, Targeting Tesla with Bold Pricing and High-Tech Features
- Black Sesame Maps Expansion Into Robotics With New Edge AI Strategy
- Wuhan's 'Black Tech' Powers China's Cross-Border Push with Niche Electronics and Scientific Firepower
- Maven 干货 全篇共:28232 字。预计阅读时间:110 分钟。建议收藏!
- IT运维必会的30个工具(it运维工具软件)
- 开源项目有你需要的吗?(开源项目什么意思)
- 自动化测试早就跑起来了,为什么测试管理还像在走路?
- Cursor 最强竞争对手来了,专治复杂大项目,免费一个月
- Cursor 太贵?这套「Cline+OpenRouter+Deepseek+Trae」组合拳更香
- 为什么没人真的用好RAG,坑都在哪里? 谈谈RAG技术架构的演进方向
- 标签列表
-
- ifneq (61)
- 字符串长度在线 (61)
- messagesource (56)
- aspose.pdf破解版 (56)
- promise.race (63)
- 2019cad序列号和密钥激活码 (62)
- window.performance (66)
- qt删除文件夹 (72)
- mysqlcaching_sha2_password (64)
- ubuntu升级gcc (58)
- nacos启动失败 (64)
- ssh-add (70)
- jwt漏洞 (58)
- macos14下载 (58)
- yarnnode (62)
- abstractqueuedsynchronizer (64)
- source~/.bashrc没有那个文件或目录 (65)
- springboot整合activiti工作流 (70)
- jmeter插件下载 (61)
- 抓包分析 (60)
- idea创建mavenweb项目 (65)
- vue回到顶部 (57)
- qcombobox样式表 (68)
- tomcatundertow (58)
- pastemac (61)
本文暂时没有评论,来添加一个吧(●'◡'●)