Drools(JBoss Rules )具有一个易于访问企业策略、易于调整以及易于管理的开源业务规则引擎,符合业内标准,速度快、效率高。业务分析师或审核人员可以利用它轻松查看业务规则,从而检验是否已编码的规则执行了所需的业务规则。
pom.xml
文件,内容:引入单元测试、drools、slf4j包
<properties>
<drools-version>7.0.0.Finaldrools-version>
properties>
<dependencies>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.12version>
dependency>
<dependency>
<groupId>org.droolsgroupId>
<artifactId>drools-compilerartifactId>
<version>${drools-version}version>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-log4j12artifactId>
<version>1.7.21version>
dependency>
dependencies>
com.mylitboy.drools.model.Product.java
文件,内容:类型及折扣
/** 产品类 */
public class Product {
// 钻石
public static final String DIAMOND = "0";
// 黄金
public static final String GOLD = "1";
// 类别
private String type;
// 折扣
private int discount;
// Getter/Setter
}
resources/com/rules/Rules.drl
文件,内容为相关规则内容。
package com.rules
import com.mylitboy.drools.model.Product
rule Offer4Diamond
when
productObject : Product(type==Product.DIAMOND)
then
productObject.setDiscount(15);
end
rule Offer4Gold
when
productObject : Product(type==Product.GOLD)
then
productObject.setDiscount(30);
end
Test.java
文件,用于单元测试规则引擎。
@Test
public void oldExecuteDrools() {
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
// 添加规则文件。
kbuilder.add(ResourceFactory.newClassPathResource("com/rules/Rules.drl", this.getClass()), ResourceType.DRL);
// 校验规则是否有问题。
if (kbuilder.hasErrors()) {
System.out.println(kbuilder.getErrors().toArray());
}
// 获取规则中的包
Collection<KnowledgePackage> pkgs = kbuilder.getKnowledgePackages();
// 添加规则中的包到规则base
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
// 将KnowledgePackage 集合添加到KnowledgeBase中
kbase.addKnowledgePackages(pkgs);
// 获取KnowledgeSession
StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
Product product = new Product();
product.setType(Product.GOLD);
// 引入匹配请求
ksession.insert(product);
// 匹配所有规则
ksession.fireAllRules();
// 销毁
ksession.dispose();
System.out.println("The discount for the product " + product.getType() + " is " + product.getDiscount() + "%");
}
运行单元测试,结果如下:
The discount for the product 1 is 30%
com.mylitboy.drools.model.Product.java
文件,内容:类型及折扣,参考Drools 5.x版本代码
resources/com/rules/Rules.drl
文件,内容为相关规则内容,参考Drools 5.x版本代码
pom.xml
文件,引入kie-spring、kie-api、drools-compiler包:
<dependency>
<groupId>org.kiegroupId>
<artifactId>kie-springartifactId>
<version>7.9.0.Finalversion>
<exclusions>
<exclusion>
<groupId>org.springframeworkgroupId>
<artifactId>spring-txartifactId>
exclusion>
<exclusion>
<groupId>org.springframeworkgroupId>
<artifactId>spring-beansartifactId>
exclusion>
<exclusion>
<groupId>org.springframeworkgroupId>
<artifactId>spring-coreartifactId>
exclusion>
<exclusion>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
exclusion>
exclusions>
dependency>
<dependency>
<groupId>org.droolsgroupId>
<artifactId>drools-compilerartifactId>
<version>7.9.0.Finalversion>
dependency>
<dependency>
<groupId>org.kiegroupId>
<artifactId>kie-apiartifactId>
<version>RELEASEversion>
<scope>compilescope>
dependency>
新增文件:
resources/META-INF/kmodule.xml
文件
<kmodule xmlns="http://www.drools.org/xsd/kmodule">
<kbase name="rules" packages="com.rules">
<ksession name="ksession-rule"/>
kbase>
kmodule>
单元测试代码:
@Test
public void testRules() {
// 构建KisServices
KieServices ks = KieServices.Factory.get();
// 根据Classpath:MATE-INF目录加载kmodule.xml文件
KieContainer kieContainer = ks.getKieClasspathContainer();
// 获取kmodule.xml中配置的名称为ksession-rule的session,默认为有状态的。
KieSession kSession = kieContainer.newKieSession("ksession-rule");
Product product = new Product();
product.setType(Product.GOLD);
// 添加product FACT对象
kSession.insert(product);
// 进行规则判断
int count = kSession.fireAllRules();
System.out.println("命中了" + count + "条规则!");
System.out.println("商品" + product.getType() + "的商品折扣为" + product.getDiscount() + "%");
}
运行单元测试,结果如下:
命中了1条规则!
商品1的商品折扣为30%
创建SpringBoot项目
com.mylitboy.drools.model.Product.java
文件,内容同上。
resources/com/rules/Rules.drl
文件,内容同上。
DroolsAutoConfiguration.java
文件,内容:
@Configuration
public class DroolsAutoConfiguration {
private static final String RULES_PATH = "com/rules/";
@Bean
@ConditionalOnMissingBean(KieFileSystem.class)
public KieFileSystem kieFileSystem() throws IOException {
KieFileSystem kieFileSystem = getKieServices().newKieFileSystem();
for (Resource file : getRuleFiles()) {
kieFileSystem.write(ResourceFactory.newClassPathResource(RULES_PATH + file.getFilename(), "UTF-8"));
}
return kieFileSystem;
}
private Resource[] getRuleFiles() throws IOException {
ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
return resourcePatternResolver.getResources("classpath*:" + RULES_PATH + "**/*.*");
}
@Bean
@ConditionalOnMissingBean(KieContainer.class)
public KieContainer kieContainer() throws IOException {
final KieRepository kieRepository = getKieServices().getRepository();
kieRepository.addKieModule(new KieModule() {
public ReleaseId getReleaseId() {
return kieRepository.getDefaultReleaseId();
}
});
KieBuilder kieBuilder = getKieServices().newKieBuilder(kieFileSystem());
kieBuilder.buildAll();
return getKieServices().newKieContainer(kieRepository.getDefaultReleaseId());
}
private KieServices getKieServices() {
return KieServices.Factory.get();
}
@Bean
@ConditionalOnMissingBean(KieBase.class)
public KieBase kieBase() throws IOException {
return kieContainer().getKieBase();
}
@Bean
@ConditionalOnMissingBean(KieSession.class)
public KieSession kieSession() throws IOException {
return kieContainer().newKieSession();
}
@Bean
@ConditionalOnMissingBean(KModuleBeanFactoryPostProcessor.class)
public KModuleBeanFactoryPostProcessor kiePostProcessor() {
return new KModuleBeanFactoryPostProcessor();
}
}
单元测试:
@RunWith(SpringRunner.class)
@SpringBootTest
public class DroolsSpringbootApplicationTests {
@Resource
private KieSession kieSession;
@Test
public void test(){
Product product = new Product();
product.setType(Product.GOLD);
// 添加product FACT对象
kieSession.insert(product);
// 进行规则判断
int count = kieSession.fireAllRules();
System.out.println("命中了" + count + "条规则!");
System.out.println("商品" + product.getType() + "的商品折扣为" + product.getDiscount() + "%");
}
}
单元测试结果:
命中了1条规则!
商品1的商品折扣为30%