Java规则引擎Easy Rules:5分钟上手的极简规则开发框架
你是否还在为业务逻辑中大量的if-else嵌套而头疼?是否因规则变更频繁导致代码重构成本高企?Easy Rules——这款被Martin Fowler启发而诞生的Java规则引擎,能让你用极少代码实现复杂业务规则,彻底告别面条式代码。本文将带你5分钟入门,掌握用注解、API和表达式语言三种方式定义规则,以及如何在实际项目中快速集成。
为什么选择Easy Rules?
在业务系统开发中,"如果用户积分大于1000则升级会员"、"当订单金额超过500元免运费"这类条件判断无处不在。传统硬编码方式会导致:
- 条件与动作紧耦合,修改规则需重写代码
- 复杂规则嵌套形成"条件墙",可读性极差
- 规则变更风险高,可能引发连锁bug
Easy Rules作为一款轻量级规则引擎,核心优势在于:
- 极简API:仅需理解
Rule和RulesEngine两个核心概念 - 多定义方式:支持注解、流式API、表达式语言(MVEL/SpEL/JEXL)和YAML配置
- 无侵入集成:纯Java库,无需额外容器,可无缝嵌入任何项目
其设计理念源自Martin Fowler的观点:"你可以自己构建简单的规则引擎——只需创建一堆带条件和动作的对象,存储在集合中,遍历它们来评估条件和执行动作"。这正是Easy Rules的实现方式,如README.md所示,它将规则抽象为独立组件,实现业务逻辑与规则的解耦。
核心组件快速了解
Easy Rules的核心架构由四部分组成:
- Fact(事实):规则执行所需的输入数据,类似方法参数
- Rule(规则):包含
Condition(条件判断)和Action(执行动作) - RulesEngine(规则引擎):负责评估条件并执行满足条件的规则,提供两种实现:
DefaultRulesEngine:按优先级顺序执行规则InferenceRulesEngine:支持规则链式触发,直到无新规则可执行
这些组件的接口定义位于easy-rules-core/src/main/java/org/jeasy/rules/api/目录,包括Rule.java、RulesEngine.java等核心API。
5分钟上手实战
环境准备
通过Maven引入依赖(最新版本请参考README.md):
<dependency>
<groupId>org.jeasy</groupId>
<artifactId>easy-rules-core</artifactId>
<version>4.1.0</version>
</dependency>
如需使用表达式语言,可添加相应模块:
<!-- MVEL支持 -->
<dependency>
<groupId>org.jeasy</groupId>
<artifactId>easy-rules-mvel</artifactId>
<version>4.1.0</version>
</dependency>
方式一:注解驱动开发(推荐)
这是最简洁的方式,通过注解定义规则的条件和动作。以天气规则为例:
@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; // 条件:当rain为true时触发
}
@Action
public void takeAnUmbrella() {
System.out.println("It rains, take an umbrella!"); // 动作:执行具体业务逻辑
}
}
完整代码见tutorials/weather/WeatherRule.java。然后创建启动类:
public class Launcher {
public static void main(String[] args) {
// 1. 定义事实:今天下雨
Facts facts = new Facts();
facts.put("rain", true);
// 2. 注册规则
Rules rules = new Rules();
rules.register(new WeatherRule());
// 3. 执行规则
RulesEngine engine = new DefaultRulesEngine();
engine.fire(rules, facts); // 输出:It rains, take an umbrella!
}
}
运行Launcher.java,即可看到规则执行结果。这种方式将规则封装为POJO,条件与动作通过注解清晰分离,可读性极佳。
方式二:流式API定义规则
当需要动态创建规则时,可使用RuleBuilder构建规则:
Rule ageRule = new RuleBuilder()
.name("age rule")
.description("if age >= 18 then grant access")
.when(facts -> facts.get("age") >= 18) // 条件:年龄>=18
.then(facts -> System.out.println("Access granted")) // 动作:授予访问权限
.build();
核心API位于RuleBuilder.java,支持链式调用设置规则名称、描述、优先级等属性。这种方式适合在运行时根据配置动态生成规则。
方式三:表达式语言定义规则
对于非开发人员或复杂规则,可使用MVEL/SpEL等表达式语言定义,如:
// MVEL规则定义
Rule mvelRule = new MVELRule()
.name("discount rule")
.description("if order amount > 1000 then apply 10% discount")
.when("order.amount > 1000") // MVEL条件表达式
.then("order.setDiscount(0.1);"); // MVEL动作表达式
MVEL模块实现位于easy-rules-mvel/src/main/java/org/jeasy/rules/mvel/,支持从YAML文件加载规则定义,特别适合业务人员维护规则:
# discount-rule.yml
name: "discount rule"
description: "if order amount > 1000 then apply 10% discount"
condition: "order.amount > 1000"
actions:
- "order.setDiscount(0.1);"
通过MVELRuleFactory加载:
RuleFactory factory = new MVELRuleFactory(new YamlRuleDefinitionReader());
Rule rule = factory.createRule(new FileReader("discount-rule.yml"));
进阶应用场景
规则优先级与组合
当多个规则可能同时触发时,可通过@Priority注解设置执行顺序:
@Rule(name = "high priority rule", priority = 1) // 优先级数值越小越先执行
public class HighPriorityRule { ... }
对于复杂业务场景,可使用规则组合模式:
- UnitRuleGroup:组内所有规则必须全部满足
- ActivationRuleGroup:组内任意规则满足即执行
- ConditionalRuleGroup:满足条件规则后才执行其他规则
组合规则实现位于easy-rules-support/src/main/java/org/jeasy/rules/support/composite/,例如创建一个订单规则组:
RuleGroup orderRules = new UnitRuleGroup("order rules");
orderRules.addRule(new DiscountRule());
orderRules.addRule(new ShippingRule());
rules.register(orderRules);
规则监听器
通过实现RuleListener接口,可在规则执行过程中插入自定义逻辑:
public class LoggingRuleListener implements RuleListener {
@Override
public void beforeEvaluate(Rule rule, Facts facts) {
log.info("Evaluating rule: " + rule.getName());
}
}
注册监听器:
RulesEngineParameters parameters = new RulesEngineParameters()
.registerRuleListener(new LoggingRuleListener());
RulesEngine engine = new DefaultRulesEngine(parameters);
项目集成最佳实践
典型目录结构
推荐按以下结构组织规则相关代码:
src/main/java
├── com/company/rules/
│ ├── annotation/ // 注解式规则
│ ├── api/ // API定义规则
│ ├── mvel/ // 表达式规则
│ └── listener/ // 规则监听器
└── com/company/launcher/
└── RuleEngineLauncher.java // 引擎启动类
性能考量
- 对于高频执行的规则,建议使用注解或API方式,避免表达式语言解析开销
- 规则数量超过100条时,考虑使用
InferenceRulesEngine的推理模式 - 通过
RulesEngineParameters设置规则执行阈值,跳过低优先级规则
快速开始与资源
- 克隆仓库:
git clone https://gitcode.com/gh_mirrors/ea/easy-rules
Easy Rules以其"简单、愚蠢"的设计哲学,让Java开发者无需学习复杂规则引擎理论,即可快速实现业务规则的模块化。无论是电商促销、风控决策还是工作流引擎,它都能成为你简化业务逻辑的利器。现在就动手改造你的第一个if-else代码块吧!
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



