本文目录导读:

在Java中实现规则引擎,可以根据业务复杂度选择不同的方案,以下是几种常见的实现方式,从简单到复杂:
基于策略模式的简单规则引擎
适用于规则数量少、变化不频繁的场景。
// 定义规则接口
public interface Rule {
boolean evaluate(Object context);
void execute(Object context);
}
// 实现具体规则
public class AgeRule implements Rule {
private int minAge;
private int maxAge;
public AgeRule(int minAge, int maxAge) {
this.minAge = minAge;
this.maxAge = maxAge;
}
@Override
public boolean evaluate(Object context) {
User user = (User) context;
return user.getAge() >= minAge && user.getAge() <= maxAge;
}
@Override
public void execute(Object context) {
User user = (User) context;
System.out.println("年龄符合条件:" + user.getName());
}
}
// 规则引擎核心
public class SimpleRuleEngine {
private List<Rule> rules = new ArrayList<>();
public void addRule(Rule rule) {
rules.add(rule);
}
public void execute(Object context) {
for (Rule rule : rules) {
if (rule.evaluate(context)) {
rule.execute(context);
}
}
}
}
// 使用示例
public class Main {
public static void main(String[] args) {
SimpleRuleEngine engine = new SimpleRuleEngine();
engine.addRule(new AgeRule(18, 60));
engine.addRule(new VipRule());
User user = new User("张三", 25, true);
engine.execute(user);
}
}
基于Drools的规则引擎(推荐)
Drools是Java最流行的规则引擎框架,支持复杂规则和规则文件。
Maven依赖
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-core</artifactId>
<version>7.73.0.Final</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
<version>7.73.0.Final</version>
</dependency>
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-api</artifactId>
<version>7.73.0.Final</version>
</dependency>
规则文件(.drl)
package com.example.rules
import com.example.model.Order
// 规则1:VIP用户享受8折优惠
rule "VIP Discount"
when
$order: Order(vipLevel > 0, totalAmount > 100)
then
$order.setDiscount(0.8);
System.out.println("VIP用户享受8折优惠");
end
// 规则2:新用户首单优惠
rule "New User First Order"
when
$order: Order(isNewUser == true, orderCount == 0)
then
$order.setDiscount(0.5);
System.out.println("新用户首单5折优惠");
end
// 规则3:满减规则
rule "Full Reduction"
when
$order: Order(totalAmount >= 500)
then
$order.setReduction(100);
System.out.println("满500减100");
end
Java代码实现
public class DroolsRuleEngine {
private KieContainer kieContainer;
public DroolsRuleEngine(String ruleFilePath) {
KieServices kieServices = KieServices.Factory.get();
KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
// 加载规则文件
Resource resource = kieServices.getResources()
.newFileSystemResource(ruleFilePath);
kieFileSystem.write(resource);
KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem);
kieBuilder.buildAll();
if (kieBuilder.getResults().hasMessages(Message.Level.ERROR)) {
throw new RuntimeException("规则编译错误:" + kieBuilder.getResults());
}
KieModule kieModule = kieBuilder.getKieModule();
this.kieContainer = kieServices.newKieContainer(kieModule.getReleaseId());
}
public void executeRules(Object fact) {
KieSession kieSession = kieContainer.newKieSession();
kieSession.insert(fact);
kieSession.fireAllRules();
kieSession.dispose();
}
}
// 使用示例
public class Main {
public static void main(String[] args) {
DroolsRuleEngine engine = new DroolsRuleEngine("rules/order-rules.drl");
Order order = new Order();
order.setTotalAmount(600);
order.setVipLevel(1);
order.setOrderCount(0);
order.setNewUser(false);
engine.executeRules(order);
System.out.println("最终金额:" + order.getFinalAmount());
}
}
基于表达式求值的规则引擎(Groovy/Java Script)
适用于需要在运行时动态修改规则的场景。
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
public class ScriptRuleEngine {
private ScriptEngine engine;
public ScriptRuleEngine() {
ScriptEngineManager manager = new ScriptEngineManager();
this.engine = manager.getEngineByName("JavaScript");
}
public boolean evaluateRule(String expression, Map<String, Object> params) {
try {
// 设置参数
for (Map.Entry<String, Object> entry : params.entrySet()) {
engine.put(entry.getKey(), entry.getValue());
}
// 执行表达式
Object result = engine.eval(expression);
return Boolean.parseBoolean(result.toString());
} catch (ScriptException e) {
throw new RuntimeException("规则执行失败", e);
}
}
// 数据库存储规则
public void addRule(String ruleId, String expression) {
// 保存到数据库
}
// 动态加载规则
public Rule loadRule(String ruleId) {
// 从数据库加载
return new Rule() {
@Override
public boolean evaluate(Object context) {
// 将context转换为Map
Map<String, Object> params = convertToMap(context);
return evaluateRule(getExpression(), params);
}
@Override
public void execute(Object context) {
// 执行动作
}
};
}
}
可视化规则配置实现
适用于业务人员直接配置规则。
// 规则实体类
@Entity
public class RuleConfig {
@Id
private Long id;
private String ruleName;
private String conditionClass; // 条件类
private String conditionMethod; // 条件方法
private String actionClass; // 执行类
private String actionMethod; // 执行方法
private int priority;
private boolean active;
// getters and setters
}
// 可视化配置规则引擎
public class ConfigurableRuleEngine {
private List<RuleConfig> ruleConfigs;
public void execute(Object context) {
// 按优先级排序
ruleConfigs.sort(Comparator.comparingInt(RuleConfig::getPriority));
for (RuleConfig config : ruleConfigs) {
if (!config.isActive()) continue;
try {
// 反射执行条件判断
Object conditionObj = Class.forName(config.getConditionClass())
.getDeclaredConstructor().newInstance();
Method conditionMethod = conditionObj.getClass()
.getMethod(config.getConditionMethod(), Object.class);
boolean matched = (boolean) conditionMethod.invoke(conditionObj, context);
if (matched) {
// 反射执行动作
Object actionObj = Class.forName(config.getActionClass())
.getDeclaredConstructor().newInstance();
Method actionMethod = actionObj.getClass()
.getMethod(config.getActionMethod(), Object.class);
actionMethod.invoke(actionObj, context);
}
} catch (Exception e) {
log.error("规则执行失败", e);
}
}
}
}
方案选择建议
| 场景 | 推荐方案 | 优点 | 缺点 |
|---|---|---|---|
| 规则简单、数量少 | 策略模式 | 实现简单、性能好 | 扩展性差 |
| 复杂业务规则 | Drools | 功能强大、支持复杂逻辑 | 学习曲线陡 |
| 动态规则 | 表达式引擎 | 可动态修改 | 性能较差 |
| 业务人员配置 | 可视化配置 | 友好、易用 | 需要设计UI |
最佳实践
- 规则与代码分离:将规则存储在外部(配置文件、数据库)
- 规则版本管理:支持规则版本控制
- 规则测试:提供规则测试功能
- 性能监控:监控规则执行时间
- 规则审计:记录规则执行日志
选择哪种方案主要取决于你的业务复杂度、团队技术能力和维护成本考量,对于大多数企业级应用,Drools是最成熟的选择。