本文目录导读:

我为你整理一个完整的Java规则引擎实战案例,涵盖从基础到进阶的多种实现方式。
业务场景:电商订单折扣系统
- 根据用户等级、订单金额、商品类型等条件计算折扣
- 支持规则动态配置和热更新
技术方案选型
// 方案对比 1. Drools - 重型规则引擎,支持复杂规则 2. Easy Rules - 轻量级,适合简单场景 3. 自研规则引擎 - 灵活可控
案例实现
1 使用Easy Rules实现(推荐入门)
项目依赖:
<dependency>
<groupId>org.jeasy</groupId>
<artifactId>easy-rules-core</artifactId>
<version>4.1.0</version>
</dependency>
业务模型:
// 订单实体类
public class Order {
private String userId;
private double amount; // 订单金额
private int userLevel; // 用户等级 1-普通 2-VIP 3-SVIP
private String productType; // 商品类型
private double discount; // 计算后的折扣
// 构造器、getter/setter省略
}
// 用户实体类
public class User {
private String userId;
private int level; // 用户等级
private boolean isNewUser; // 是否新用户
private int orderCount; // 累计订单数
}
规则定义:
import org.jeasy.rules.annotation.*;
@Rule(name = "VIP用户折扣规则", description = "VIP用户享受9折优惠")
public class VipDiscountRule {
@Condition
public boolean isVip(@Fact("user") User user) {
return user.getLevel() >= 2;
}
@Action
public void applyDiscount(@Fact("order") Order order) {
order.setDiscount(order.getDiscount() * 0.9);
System.out.println("VIP用户折扣已应用: 9折");
}
@Priority
public int getPriority() {
return 1; // 优先级,数字越小越先执行
}
}
@Rule(name = "满减规则", description = "订单满1000减100")
public class ThresholdDiscountRule {
@Condition
public boolean isOverThreshold(@Fact("order") Order order) {
return order.getAmount() >= 1000;
}
@Action
public void applyThresholdDiscount(@Fact("order") Order order) {
double discountedAmount = order.getAmount() - 100;
order.setAmount(discountedAmount);
System.out.println("满减规则已应用: 减100元");
}
@Priority
public int getPriority() {
return 2;
}
}
@Rule(name = "新用户优惠规则", description = "新用户首次购物9.5折")
public class NewUserDiscountRule {
@Condition
public boolean isNewUser(@Fact("user") User user) {
return user.isNewUser() && user.getOrderCount() == 0;
}
@Action
public void applyNewUserDiscount(@Fact("order") Order order) {
order.setDiscount(order.getDiscount() * 0.95);
System.out.println("新用户折扣已应用: 9.5折");
}
@Priority
public int getPriority() {
return 3;
}
}
规则引擎执行器:
import org.jeasy.rules.api.*;
import org.jeasy.rules.core.*;
import java.util.ArrayList;
import java.util.List;
public class DiscountRuleEngine {
private Rules rules;
private RulesEngine rulesEngine;
public DiscountRuleEngine() {
// 初始化规则引擎
rules = new Rules();
rulesEngine = new DefaultRulesEngine();
// 配置引擎参数
RulesEngineParameters parameters = new RulesEngineParameters()
.skipOnFirstAppliedRule(false) // 是否跳过后续规则
.skipOnFirstFailedRule(false); // 失败是否继续
rulesEngine = new DefaultRulesEngine(parameters);
// 注册默认规则
registerDefaultRules();
}
private void registerDefaultRules() {
rules.register(new VipDiscountRule());
rules.register(new ThresholdDiscountRule());
rules.register(new NewUserDiscountRule());
}
// 动态添加规则
public void addRule(Object rule) {
if (rule.getClass().isAnnotationPresent(Rule.class)) {
rules.register(rule);
}
}
// 移除规则
public void removeRule(Object rule) {
rules.unregister(rule);
}
// 执行规则
public Order executeRules(Order order, User user) {
Facts facts = new Facts();
facts.put("order", order);
facts.put("user", user);
// 初始化折扣为1(无折扣)
order.setDiscount(1.0);
rulesEngine.fire(rules, facts);
return order;
}
}
使用示例:
public class RuleEngineDemo {
public static void main(String[] args) {
// 创建规则引擎
DiscountRuleEngine engine = new DiscountRuleEngine();
// 创建测试用户
User vipUser = new User("U001", 2, false, 10);
User newUser = new User("U002", 1, true, 0);
User normalUser = new User("U003", 1, false, 5);
// 创建订单
Order order1 = new Order("O001", 1500, "electronics", 1.0);
Order order2 = new Order("O002", 800, "clothing", 1.0);
Order order3 = new Order("O003", 2000, "books", 1.0);
// 执行规则计算
Order result1 = engine.executeRules(order1, vipUser);
System.out.println("VIP用户大额订单最终金额: " + result1.getAmount() * result1.getDiscount());
Order result2 = engine.executeRules(order2, newUser);
System.out.println("新用户订单最终金额: " + result2.getAmount() * result2.getDiscount());
// 动态添加规则
engine.addRule(new SpecialEventRule()); // 节假日特殊折扣
Order result3 = engine.executeRules(order3, normalUser);
}
}
2 自研规则引擎(更灵活)
// 规则接口定义
public interface BusinessRule {
boolean evaluate(OrderContext context);
OrderContext execute(OrderContext context);
int getPriority();
String getRuleName();
}
// 上下文对象
public class OrderContext {
private Order order;
private User user;
private Map<String, Object> attributes = new HashMap<>();
private List<String> appliedRules = new ArrayList<>();
// 添加已应用规则记录
public void addAppliedRule(String ruleName) {
appliedRules.add(ruleName);
}
// getter/setter省略
}
// 具体规则实现
public class VipUserRule implements BusinessRule {
@Override
public boolean evaluate(OrderContext context) {
User user = context.getUser();
return user.getLevel() >= 2;
}
@Override
public OrderContext execute(OrderContext context) {
Order order = context.getOrder();
double newDiscount = order.getDiscount() * 0.9;
order.setDiscount(newDiscount);
context.addAppliedRule("VIP用户折扣");
return context;
}
@Override
public int getPriority() {
return 1;
}
@Override
public String getRuleName() {
return "vip_discount";
}
}
// 规则引擎核心
public class CustomRuleEngine {
private List<BusinessRule> rules = new ArrayList<>();
// 规则排序
public void addRule(BusinessRule rule) {
rules.add(rule);
rules.sort(Comparator.comparingInt(BusinessRule::getPriority));
}
// 执行所有规则
public Order execute(Order order, User user) {
OrderContext context = new OrderContext();
context.setOrder(order);
context.setUser(user);
order.setDiscount(1.0);
for (BusinessRule rule : rules) {
if (rule.evaluate(context)) {
context = rule.execute(context);
System.out.println("执行规则: " + rule.getRuleName() + ", 当前折扣: " +
order.getDiscount() * 100 + "%");
}
}
return order;
}
// 从配置文件加载规则
public void loadRulesFromConfig(String configPath) {
// 通过反射或配置加载规则
// 支持规则热更新
}
}
// XML配置规则示例
/*
<rules>
<rule name="vip" class="com.example.rules.VipUserRule" enabled="true"/>
<rule name="threshold" class="com.example.rules.ThresholdRule" enabled="true"/>
</rules>
*/
3 规则管理界面(Spring Boot集成)
@RestController
@RequestMapping("/api/rules")
public class RuleController {
private final DiscountRuleEngine ruleEngine;
@Autowired
public RuleController(DiscountRuleEngine ruleEngine) {
this.ruleEngine = ruleEngine;
}
// 查看所有规则
@GetMapping
public List<RuleInfo> getAllRules() {
// 返回规则信息列表
}
// 添加新规则
@PostMapping
public ResponseEntity<String> addRule(@RequestBody RuleDefinition ruleDef) {
try {
// 动态创建规则实例
Object rule = createRuleFromDefinition(ruleDef);
ruleEngine.addRule(rule);
return ResponseEntity.ok("规则添加成功");
} catch (Exception e) {
return ResponseEntity.badRequest().body("规则添加失败: " + e.getMessage());
}
}
// 更新规则
@PutMapping("/{ruleId}")
public ResponseEntity<String> updateRule(@PathVariable String ruleId,
@RequestBody RuleDefinition ruleDef) {
// 更新规则逻辑
}
// 删除规则
@DeleteMapping("/{ruleId}")
public ResponseEntity<String> deleteRule(@PathVariable String ruleId) {
// 删除规则逻辑
}
// 规则排序
@PostMapping("/reorder")
public ResponseEntity<String> reorderRules(@RequestBody List<String> ruleOrder) {
// 调整规则优先级
}
// 模拟测试规则
@PostMapping("/test")
public ResponseEntity<Order> testRules(@RequestBody TestRequest request) {
Order order = new Order();
// 填充order和user信息
Order result = ruleEngine.executeRules(order, request.getUser());
return ResponseEntity.ok(result);
}
}
// 规则定义DTO
public class RuleDefinition {
private String name; // 规则名称
private String condition; // 条件表达式
private List<String> actions; // 执行动作
private int priority; // 优先级
private boolean enabled; // 是否启用
// getter/setter省略
}
最佳实践建议
1 性能优化
// 规则缓存
@Service
public class RuleCache {
private Cache<String, List<BusinessRule>> ruleCache;
public void invalidateCache(String userId) {
// 用户规则变化时清除缓存
}
public List<BusinessRule> getCachedRules(String userId) {
// 优先从缓存获取
return ruleCache.get(userId, key -> loadRulesFromDB(key));
}
}
2 调试和监控
// 规则执行日志
@Aspect
@Component
public class RuleExecutionLogger {
@Around("@annotation(LogRuleExecution)")
public Object logExecution(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();
Object result = joinPoint.proceed();
long duration = System.currentTimeMillis() - start;
// 记录规则执行时间和结果
log.info("规则执行耗时: {}ms, 结果: {}", duration, result);
return result;
}
}
3 规则版本管理
public class RuleVersion {
private String ruleId;
private int version;
private String content;
private boolean active;
private Date deployTime;
// 支持规则灰度发布
public boolean shouldDeploy(String userId) {
// 基于userId的hash决定是否启用新版本
int hash = Math.abs(userId.hashCode());
return hash % 100 < trafficPercentage;
}
}
生产环境注意事项
- 规则数量限制:单个业务场景建议不超过20条规则
- 规则优先级管理:明确规则执行顺序,避免冲突
- 超时控制:每个规则执行时间建议在100ms以内
- 幂等性:确保规则执行结果可重复,不影响业务数据
- 审计日志:记录规则决策路径,便于问题排查
- 回滚机制:支持规则快速回滚,降低变更风险
这个案例涵盖了Java规则引擎的主流实现方式,实际项目中选择方案时,根据业务复杂度、团队技术栈、维护成本等因素综合权衡,对于简单场景,自研或Easy Rules更轻量;复杂场景,Drools等重型引擎更适合。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
足球直播
足球直播
足球直播
篮球直播
篮球直播
篮球直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
亚冠直播
亚冠直播
亚冠直播
欧冠直播
欧冠直播
欧冠直播
英超直播
英超直播
英超直播
西甲直播
西甲直播
西甲直播
中超直播
中超直播
中超直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
曼联直播
曼联直播
曼联直播
日职联直播
日职联直播
日职联直播
澳超直播
澳超直播
澳超直播
阿森纳直播
阿森纳直播
阿森纳直播
足球直播
足球直播
足球直播
NBA直播
NBA直播
NBA直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
欧冠直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播
中超直播