Easy Rules 配置文件外置-Mysql
场景
前一篇,介绍了Easy Rules作为Java一款轻量级的规则引擎,使得研发更加注重于纯业务开发,提高开发效率。
这一篇,主要是围绕,规则配置数据,外置于数据库Mysql的实现。
思路
1、Mysql存储
新建表t_biz_rule、t_biz_rule_compose分别存储规则定义、规则组合定义
2、构建Rules
- Mysql中的Rule、RuleCompose转换成RuleDefinition对象
- 定义Rules注册工具类Helper,为每个RuleCompose注册
3、定义Facts以及RulesEngine
实现
1、Mysql实现规则配置的CRUD
定义对象BizRule
@Data @Accessors(chain = true) public class BizRule implements Serializable { /** * 主键ID */ private Long id; /** * 规则组 */ private String groupCode; /** * 规则名称 */ private String name; /** * 规则描述 */ private String description; /** * 规则权重 */ private int priority; /** * 规则组合类型(compositeRuleType) * {@link CompositeRuleTypeEnum} */ private Integer compositeType; /** * 状态 0有效-1无效 */ private Integer status; /** * 创建时间 */ private Date createTime; /** * 变更时间 */ private Date updateTime; }
定义对象BizRuleCompose
@Data @Accessors(chain = true) public class BizRuleCompose implements Serializable { /** * 主键ID */ private Long id; /** * 规则ID */ private Long ruleId; /** * 规则名称 */ private String name; /** * 规则描述 */ private String description; /** * 规则权重 */ private int priority; /** * 规则条件(Java代码) */ private String condition; /** * 执行操作 */ private String actions; /** * 状态 0有效-1无效 */ private Integer status; /** * 创建时间 */ private Date createTime; }
定义CRUD参数Bo
@Data public class BizRuleBo implements Serializable { /** * 名称 */ @NotNull(message = "请输入规则名称") @Size(min = 2, max = 50, message = "规则名称2-50个字符") private String name; /** * 描述 */ @NotNull(message = "请输入规则描述") @Size(min = 2, max = 20, message = "规则名称2-10个字符") private String description; /** * 规则组 */ @NotNull(message = "请定义规则组") @Size(min = 2, max = 10, message = "规则名称2-10个字符") private String groupCode; /** * 权限 */ private int priority; /** * 组合类型 */ private Integer compositeType; /** * 组合规则 */ private List<BizComposeBo> composingRules; }
API实现
@RestController @RequestMapping("biz_rule") @AllArgsConstructor @Validated public class BizRuleController { private BizRuleService bizRuleService; @AuthIgnore @PostMapping("/add") @OperationLog(value = "业务规则新建", type = LogOperationEnum.ADD) public ResultVo<Integer> add(@RequestBody @Valid BizRuleBo bo) { return ResultVo.success(bizRuleService.addRule(bo)); } }
POST请求结果
规则配置新增操作
2、通过Heler工具类构建Rules对象
定义BizRuleHelper
public class BizRuleHelper extends AbstractRuleFactory { private final ParserContext parserContext; public BizRuleHelper(ParserContext parserContext) { this.parserContext = parserContext; } /** * 创建规则 * @param ruleDefinitions 规则定义 * @return 结果 */ public Rules createRules(List<RuleDefinition> ruleDefinitions) { Rules rules = new Rules(); ruleDefinitions.forEach(ruleDefinition -> rules.register(createRule(ruleDefinition))); return rules; } @Override public Rule createSimpleRule(RuleDefinition ruleDefinition) { MVELRule mvelRule = new MVELRule(parserContext) .name(ruleDefinition.getName()) .description(ruleDefinition.getDescription()) .priority(ruleDefinition.getPriority()) .when(ruleDefinition.getCondition()); for (String action : ruleDefinition.getActions()) { mvelRule.then(action); } return mvelRule; } }
定义RulesConfig
@Component @AllArgsConstructor public class BizRulesConfig { private BizRuleService bizRuleService; static String group_code = "order_rule"; /** * 构建rules配置 */ public Rules fetchConfigRules() { //JSON 表达式 BizRuleHelper bizRuleHelper = new BizRuleHelper(new ParserContext()); return bizRuleHelper.createRules(bizRuleService.ruleDefinitions(group_code)); } }
3、API代码
@AuthIgnore @OperationLog(value = "easy rules DB测试") @PostMapping("/db") @SneakyThrows public ResultVo<?> dbTest(@RequestBody BizOrder order) { //定义数据 Facts facts = new Facts(); facts.put("param", order); facts.put("OrderService",OrderService.class); //读取配置 Rules rules = bizRulesConfig.fetchConfigRules(); //引擎配置 RulesEngine rulesEngine = new DefaultRulesEngine(); rulesEngine.fire(rules, facts); return ResultVo.success(); }
4、场景模拟
和前一篇类似,模拟商品1,是打折商品,原价200,折扣7折,计算最后价格。
模拟请求参数