<dependency> <groupId>org.drools</groupId> <artifactId>drools-core</artifactId> <version>7.59.0.Final</version> </dependency> <dependency> <groupId>org.drools</groupId> <artifactId>drools-compiler</artifactId> <version>7.59.0.Final</version> </dependency> <dependency> <groupId>org.drools</groupId> <artifactId>drools-decisiontables</artifactId> <version>7.59.0.Final</version> </dependency>Drools配置类
@Configuration public class DroolsConfig { // 制定规则文件的路径 private static final String RULES_CUSTOMER_RULES_DRL = "rules/customer-discount.drl"; private static final KieServices kieServices = KieServices.Factory.get(); @Bean public KieContainer kieContainer() { KieFileSystem kieFileSystem = kieServices.newKieFileSystem(); kieFileSystem.write(ResourceFactory.newClassPathResource(RULES_CUSTOMER_RULES_DRL)); KieBuilder kb = kieServices.newKieBuilder(kieFileSystem); kb.buildAll(); KieModule kieModule = kb.getKieModule(); KieContainer kieContainer = kieServices.newKieContainer(kieModule.getReleaseId()); return kieContainer; } }定义了一个 KieContainer的Spring Bean ,KieContainer用于通过加载应用程序的/resources文件夹下的规则文件来构建规则引擎。
//堆代码 duidaima.com @Getter @Setter public class OrderRequest { /** * 客户号 */ private String customerNumber; /** * 年龄 */ private Integer age; /** * 订单金额 */ private Integer amount; /** * 客户类型 */ private CustomerType customerType; }此外,定义一个客户类型CustomerType 的枚举,规则引擎会根据该值计算客户订单折扣百分比,如下所示。
public enum CustomerType { LOYAL, NEW, DISSATISFIED; public String getValue() { return this.toString(); } }最后,创建一个订单折扣类 OrderDiscount ,用来表示计算得到的最终的折扣,如下所示。
@Getter @Setter public class OrderDiscount { /** * 折扣 */ private Integer discount = 0; }我们将使用上述响应对象返回计算出的折扣。
这个drl文件虽然不是java文件,但还是很容易看懂的。
.我们使用了一个名为orderDiscount 的全局参数,可以在多个规则之间共享。
.drl 文件可以包含一个或多个规则。我们可以使用mvel语法来指定规则。此外,每个规则使用rule关键字进行描述。
.每个规则when-then语法来定义规则的条件。
.根据订单请求的输入值,我们正在为结果添加折扣。如果规则表达式匹配,每个规则都会向全局结果变量添加额外的折扣。import com.alvin.drools.model.OrderRequest; import com.alvin.drools.model.CustomerType; global com.alvin.drools.model.OrderDiscount orderDiscount; dialect "mvel" // 堆代码 duidaima.com // 规则1: 根据年龄判断 rule "Age based discount" when // 当客户年龄在20岁以下或者50岁以上 OrderRequest(age < 20 || age > 50) then // 则添加10%的折扣 System.out.println("==========Adding 10% discount for Kids/ senior customer============="); orderDiscount.setDiscount(orderDiscount.getDiscount() + 10); end // 规则2: 根据客户类型的规则 rule "Customer type based discount - Loyal customer" when // 当客户类型是LOYAL OrderRequest(customerType.getValue == "LOYAL") then // 则增加5%的折扣 System.out.println("==========Adding 5% discount for LOYAL customer============="); orderDiscount.setDiscount(orderDiscount.getDiscount() + 5); end rule "Customer type based discount - others" when OrderRequest(customerType.getValue != "LOYAL") then System.out.println("==========Adding 3% discount for NEW or DISSATISFIED customer============="); orderDiscount.setDiscount(orderDiscount.getDiscount() + 3); end rule "Amount based discount" when OrderRequest(amount > 1000L) then System.out.println("==========Adding 5% discount for amount more than 1000$============="); orderDiscount.setDiscount(orderDiscount.getDiscount() + 5); end添加Service层
@Service public class OrderDiscountService { // 堆代码 duidaima.com @Autowired private KieContainer kieContainer; public OrderDiscount getDiscount(OrderRequest orderRequest) { OrderDiscount orderDiscount = new OrderDiscount(); // 开启会话 KieSession kieSession = kieContainer.newKieSession(); // 设置折扣对象 kieSession.setGlobal("orderDiscount", orderDiscount); // 设置订单对象 kieSession.insert(orderRequest); // 触发规则 kieSession.fireAllRules(); // 中止会话 kieSession.dispose(); return orderDiscount; } }.注入KieContainer实例并创建一个KieSession实例。
.最后通过调用KieSession 的dispose()方法终止会话。
@RestController public class OrderDiscountController { @Autowired private OrderDiscountService orderDiscountService; @PostMapping("/get-discount") public ResponseEntity<OrderDiscount> getDiscount(@RequestBody OrderRequest orderRequest) { OrderDiscount discount = orderDiscountService.getDiscount(orderRequest); return new ResponseEntity<>(discount, HttpStatus.OK); } }测试一下
总结