Java规则引擎案例

wen java案例 2

本文目录导读:

Java规则引擎案例

  1. 技术方案选型
  2. 案例实现
  3. 最佳实践建议
  4. 生产环境注意事项

我为你整理一个完整的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;
    }
}

生产环境注意事项

  1. 规则数量限制:单个业务场景建议不超过20条规则
  2. 规则优先级管理:明确规则执行顺序,避免冲突
  3. 超时控制:每个规则执行时间建议在100ms以内
  4. 幂等性:确保规则执行结果可重复,不影响业务数据
  5. 审计日志:记录规则决策路径,便于问题排查
  6. 回滚机制:支持规则快速回滚,降低变更风险

这个案例涵盖了Java规则引擎的主流实现方式,实际项目中选择方案时,根据业务复杂度、团队技术栈、维护成本等因素综合权衡,对于简单场景,自研或Easy Rules更轻量;复杂场景,Drools等重型引擎更适合。

抱歉,评论功能暂时关闭!