场景
之前介绍了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 composingRules;
}
API实现
@RestController
@RequestMapping("biz_rule")
@AllArgsConstructor
@Validated
public class BizRuleController {
private BizRuleService bizRuleService;
@AuthIgnore
@PostMapping("/add")
@OperationLog(value = "业务规则新建", type = LogOperationEnum.ADD)
public ResultVo 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 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折,计算最后价格。
我们可以看出,通过调用统一接口/order/db,最终还是执行了折扣的业务逻辑。
内容出处:,
声明:本网站所收集的部分公开资料来源于互联网,转载的目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。如果您发现网站上有侵犯您的知识产权的作品,请与我们取得联系,我们会及时修改或删除。文章链接:http://www.yixao.com/procedure/18275.html