Drools規則引擎入門
Drools(JBoss Rules )具有一個易于通路企業政策、易于調整以及易于管理的開源業務規則引擎,符合業内标準,速度快、效率高。業務分析師或稽核人員可以利用它輕松檢視業務規則,進而檢驗是否已編碼的規則執行了所需的業務規則。
Drools 5.x版本代碼(淘汰)
pom.xml
檔案,内容:引入單元測試、drools、slf4j包
<properties>
<drools-version>7.0.0.Final</drools-version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
<version>${drools-version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.21</version>
</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%
Drools 7.x版本代碼
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.kie</groupId>
<artifactId>kie-spring</artifactId>
<version>7.9.0.Final</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
<version>7.9.0.Final</version>
</dependency>
<dependency>
<groupId>org.kie</groupId>
<artifactId>kie-api</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
新增檔案:
resources/META-INF/kmodule.xml
檔案
<?xml version="1.0" encoding="utf-8" ?>
<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%
Drools內建至SpringBoot
建立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%