引言
在日常业务开发中,我们常常会遇到复杂的业务规则判断,例如订单优惠计算、风控决策、审批流程等。如果将所有规则写死在if-else结构中,不仅代码臃肿,还难以维护和扩展。为解决这一问题,规则引擎应运而生。Easy Rules作为一款轻量级的Java规则引擎框架,通过POJO和注解简化了业务规则的管理与执行,特别适合简单业务逻辑处理场景。

Easy Rules核心概念
Easy Rules基于规则引擎的常见原则和概念,其核心组件包括:
- Rule(规则):规则是Easy Rules框架的核心,定义了业务规则的完整逻辑。
- Condition(条件):定义规则的前提条件,当条件为true时,规则将被触发。
- Action(动作):规则触发后执行的代码逻辑。
- Facts(实际):输入数据的集合,作为规则条件判断的依据。
- Priority(优先级):定义规则执行的优先顺序。
Easy Rules基础使用示例
以下是一个简单的规则引擎使用示例,用于判断用户是否可以购买酒类产品:
import org.jeasy.rules.annotation.Condition;
import org.jeasy.rules.annotation.Rule;
import org.jeasy.rules.api.Facts;
import org.jeasy.rules.api.Rules;
import org.jeasy.rules.core.RulesImpl;
import org.jeasy.rules.core.DefaultRulesEngine;
@Rule(name = "age rule", description = "Check if user is of legal age to buy alcohol")
public class AgeRule {
@Condition
public boolean checkAge(@Fact("age") int age) {
return age >= 18;
}
@Action
public void buyAlcohol(Facts facts) {
System.out.println("User is allowed to buy alcohol");
}
}
// 使用示例
public class RuleEngineDemo {
public static void main(String[] args) {
AgeRule ageRule = new AgeRule();
Rules rules = new RulesImpl();
rules.register(ageRule);
DefaultRulesEngine rulesEngine = new DefaultRulesEngine();
Facts facts = new Facts();
facts.put("age", 20);
rulesEngine.fire(rules, facts);
}
}
Easy Rules与Spring Boot集成实践

基础集成
在Spring Boot项目中集成Easy Rules超级简单,只需添加依赖:
<dependency>
<groupId>org.jeasy</groupId>
<artifactId>easy-rules-core</artifactId>
<version>3.0.0</version>
</dependency>
创建规则类并注册到Spring容器中:
import org.jeasy.rules.annotation.Action;
import org.jeasy.rules.annotation.Condition;
import org.jeasy.rules.annotation.Priority;
import org.jeasy.rules.annotation.Rule;
import org.jeasy.rules.api.Facts;
@Rule(name = "执行STEP_1", description = "执行第一步处理")
public class Priority100RequestService {
@Condition
public boolean condition() {
return true;
}
@Action
public void action(Facts facts) {
System.out.println("规则引擎执行STEP_1:开始处理");
String step1Input = (String) facts.get("STEP_1_INPUT");
System.out.println("STEP_1入参:" + step1Input);
// 设置STEP_2的输入参数
facts.put("STEP_2_INPUT", "来自STEP_1的数据");
System.out.println("规则引擎执行STEP_1:结束处理");
}
@Priority
public int priority() {
return 100;
}
}
创建控制器来触发规则执行:
import org.jeasy.rules.api.Facts;
import org.jeasy.rules.api.Rules;
import org.jeasy.rules.core.DefaultRulesEngine;
import org.jeasy.rules.core.RulesEngineParameters;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/rules")
public class RuleController {
@GetMapping("/execute")
public String executeRules() {
// 创建规则引擎参数
RulesEngineParameters parameters = new RulesEngineParameters()
.skipOnFirstAppliedRule(false);
// 创建规则引擎
RulesEngine rulesEngine = new DefaultRulesEngine(parameters);
// 创建规则集
Rules rules = new Rules();
rules.register(new Priority100RequestService());
rules.register(new Priority101RequestService());
// 创建实际
Facts facts = new Facts();
facts.put("STEP_1_INPUT", "初始输入数据");
// 执行规则
rulesEngine.fire(rules, facts);
// 返回最终结果
return facts.get("FINAL_OUTPUT").toString();
}
}
高级集成模式
在实际生产环境中,我们一般需要更灵活的规则管理方式。Easy Rules可以与Spring Boot结合,实现规则的动态加载和配置。
关键组件设计
- AdapterRule 接口:所有自定义规则需实现此接口
- AutoCreateFactory 工厂类:基于@AutoCreate注解自动扫描和创建规则实例
- RefUtils 反射工具类:负责包扫描和类加载
实现步骤
- 定义规则接口:
public interface AdapterRule {
}
- 创建带注解的规则实现:
import org.jeasy.rules.annotation.AutoCreate;
import org.jeasy.rules.annotation.Rule;
import org.jeasy.rules.annotation.Condition;
import org.jeasy.rules.annotation.Priority;
import org.jeasy.rules.api.Facts;
@AutoCreate(value = "MyAppCode", sign = {"STEP_1", "DEFAULT"}, isSingleton = true)
@Rule(name = "执行STEP_1", description = "执行STEP_1")
public class Priority100RequestService implements AdapterRule {
@Condition
public boolean condition() {
return true;
}
@Action
public void action(Facts facts) {
System.out.println("执行STEP_1:开始");
String step1Input = (String) facts.get("STEP_1_INPUT");
System.out.println("STEP_1入参:" + step1Input);
facts.put("STEP_2_INPUT", "STEP_1出参=STEP_2入参");
System.out.println("执行STEP_1:结束");
}
@Priority
public int priority() {
return 100;
}
}
- 实现AutoCreateFactory:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.stream.Collectors;
@Component
public class AutoCreateFactory {
private final List<AdapterRule> rules = new ArrayList<>();
private final Map<String, List<AdapterRule>> ruleMap = new HashMap<>();
@Autowired
public AutoCreateFactory(List<AdapterRule> allRules) {
// 按注解属性分类规则
for (AdapterRule rule : allRules) {
AutoCreate autoCreate = rule.getClass().getAnnotation(AutoCreate.class);
if (autoCreate != null) {
// 根据value分组
String appCode = autoCreate.value();
ruleMap.computeIfAbsent(appCode, k -> new ArrayList<>()).add(rule);
// 根据sign分组
for (String sign : autoCreate.sign()) {
ruleMap.computeIfAbsent(sign, k -> new ArrayList<>()).add(rule);
}
}
}
}
public List<AdapterRule> getRules(String appCode) {
return ruleMap.getOrDefault(appCode, Collections.emptyList());
}
public List<AdapterRule> getRulesBySign(String sign) {
return ruleMap.getOrDefault(sign, Collections.emptyList());
}
}
- 在Spring Boot应用中使用:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/rules")
public class RuleController {
@Autowired
private AutoCreateFactory autoCreateFactory;
@GetMapping("/execute")
public String executeRules() {
// 获取规则
List<AdapterRule> rules = autoCreateFactory.getRulesBySign("STEP_1");
// 创建规则引擎
RulesEngineParameters parameters = new RulesEngineParameters()
.skipOnFirstAppliedRule(false);
RulesEngine rulesEngine = new DefaultRulesEngine(parameters);
// 创建规则集
Rules rulesSet = new Rules();
rules.forEach(rulesSet::register);
// 创建实际
Facts facts = new Facts();
facts.put("STEP_1_INPUT", "初始输入数据");
// 执行规则
rulesEngine.fire(rulesSet, facts);
return facts.get("FINAL_OUTPUT").toString();
}
}
Easy Rules的优势
- 解耦业务逻辑:将业务规则与程序代码解耦,提高系统的灵活性和可维护性
- 动态规则加载:支持动态加载和更新规则,无需重启应用
- 易于测试和调试:规则独立,便于单元测试和问题排查
- 轻量级:无需复杂的配置,与Spring Boot无缝集成
- 注解驱动:通过POJO和注解简化规则定义,降低学习成本
适用场景

Easy Rules特别适合以下场景:
- 简单的业务规则判断(如订单优惠计算、用户等级判断)
- 需要频繁调整的业务规则(如风控策略、审批流程)
- 需要快速实现业务决策的场景
- 作为复杂规则引擎的轻量级替代方案
Easy Rules作为一款轻量级Java规则引擎框架,通过POJO和注解简化了业务规则的管理与执行,特别适合简单业务逻辑处理场景。在Spring Boot项目中集成Easy Rules,可以有效解耦业务逻辑,提高系统的灵活性和可维护性。通过高级集成模式,我们还可以实现规则的动态加载和配置,满足生产环境的实际需求。
© 版权声明
文章版权归作者所有,未经允许请勿转载。





我不信最底层,不是if else
昨天才刷到liteFlow 今天就来easyRules
多种规则引擎框架
并发bug
规则引擎
💗感谢分享
真不戳💪
收藏了,感谢分享