前面寫過一篇 Drools 規則引擎相關的文章,這篇文章主要記錄一下規則引擎的環境搭建和簡單示例。不熟悉 drools 的朋友能夠看看這篇文章: 本身寫個 Drools 文件語法檢查工具——棧的應用之編譯器檢測語法錯誤
介紹的內容:html
環境: idea + jdk1.8 + gradle
我用的是 gradle 構建 java 工程的方式、用 maven 構建的能夠參考配置java
構造這樣一個需求背景,雙十一來了,商品打折,假設商品價格 (0,500], 打85折,商品價格 (500, 1000],打8折, 商品價格 (1000,∞), 一概減 300。api
新建一個 gradle 項目,建立包:com.sharpcj
,新建類 Product.java
和 Main.java
:
session
Product.java
文件以下:app
package com.sharpcj; public class Product { private String name; // 商品名稱 private double prePrice; // 商品訂價 private double realPrice; //商品實際售價 public Product() { } public Product(String name, double prePrice) { this.name = name; this.prePrice = prePrice; } public String getName() { return name; } public void setName(String name) { this.name = name; } public double getPrePrice() { return prePrice; } public void setPrePrice(double prePrice) { this.prePrice = prePrice; } public double getRealPrice() { return realPrice; } public void setRealPrice(double realPrice) { this.realPrice = realPrice; } }
而後在 Main.java
新建 main 方法。less
打開 build.gradle
文件,添加相應的插件和依賴maven
plugins { id 'java' } plugins { id 'application' } mainClassName = 'com.sharpcj.Main' group 'com.sharpcj' version '1.0-SNAPSHOT' sourceCompatibility = 1.8 repositories { mavenCentral() } dependencies { testCompile group: 'junit', name: 'junit', version: '4.12' compile group: 'org.kie', name: 'kie-api', version: '7.5.0.Final' compile group: 'org.drools', name: 'drools-compiler', version: '7.5.0.Final' }
引入 Java 插件,使Gradle能夠構建Java代碼,同時引入了執行Drools依賴的兩個庫, 指定了 mainClassName
。ide
在 resources
目錄下面新建包 demo.rules
,用來存放 drools 規則文件。而後新建文件 product.drl
,
工具
內容以下:測試
package com.sharpcj; rule "Product price less than 500" // 給規則取個名 when pp : Product( prePrice <= 500 ) // 規則 then // 符合規則後執行的操做,是Java代碼 double prePrice = pp.getPrePrice(); pp.setRealPrice(prePrice * 0.85); System.out.println(pp.getName() + "活動價是:" + pp.getRealPrice()); end rule "Product price less than 1000" // 給規則取個名 when p : Product( prePrice > 500 && prePrice <=1000 ) // 規則 then // 符合規則後執行的操做,是Java代碼 double prePrice = p.getPrePrice(); p.setRealPrice(prePrice * 0.8); System.out.println(p.getName() + "活動價是:" + p.getRealPrice()); end rule "Product price more than 1000" // 給規則取個名 when p : Product( prePrice > 1000 ) // 規則 then // 符合規則後執行的操做,是Java代碼 double prePrice = p.getPrePrice(); p.setRealPrice(prePrice - 300); System.out.println(p.getName() + "活動價是:" + p.getRealPrice()); end
運行 drools 須要一個固定的配置文件,在 resources
文件下的目錄 META_INF
,名稱固定爲 kmodule.xml
:
配置文件至少包含以下幾行:
<kmodule xmlns="http://www.drools.org/xsd/kmodule"> <kbase name="kbase1" packages="demo.rules"> <ksession name="ksession1" /> </kbase> </kmodule>
配置簡單說明:
在 Main.java
類中編寫測試方法,讓規則文件跑起來:
package com.sharpcj; import org.kie.api.KieServices; import org.kie.api.runtime.KieContainer; import org.kie.api.runtime.KieSession; public class Main { public static void main(String[] args){ new Main().test(); } private void test(){ // 構建KieServices KieServices ks = KieServices.Factory.get(); KieContainer kc = ks.getKieClasspathContainer(); // 獲取kmodule.xml中配置中名稱爲ksession-rule的session,默認爲有狀態的。 KieSession kSession = kc.newKieSession("ksession1"); Product fan = new Product("電扇", 280); Product washer = new Product("洗衣機",2200); Product phone = new Product("手機", 998); kSession.insert(fan); kSession.insert(washer); kSession.insert(phone); kSession.fireAllRules(); kSession.dispose(); } }
運行結果:
上面使用的配置文件形式加載 drools 文件是 drools 7.x 版本纔有的,在此以前,咱們一般使用代碼形式加載規則文件,固然在 drools 7.x 中依然可使用這種方式,只不過有些 API 已通過時了,或者更新了。下面用代碼形式加載規則文件代碼以下:
/** * 不使用 drools 7.x 配置文件 */ private void test2(){ KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); kbuilder.add(ResourceFactory.newClassPathResource("demo/rules/product.drl"), ResourceType.DRL); KnowledgeBuilderErrors errors = kbuilder.getErrors(); if (errors.size() > 0) { for (KnowledgeBuilderError error: errors) { System.err.println(error); } throw new IllegalArgumentException("Could not parse knowledge."); } // 註釋掉的是 drools 6.x API /*KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(); kbase.addKnowledgePackages(kbuilder.getKnowledgePackages()); StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();*/ // drools 7.x API InternalKnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(); Collection<KiePackage> pkgs = kbuilder.getKnowledgePackages(); kbase.addPackages(pkgs); KieSession kieSession = kbase.newKieSession(); Product fan = new Product("電扇", 280); Product washer = new Product("洗衣機",2200); Product phone = new Product("手機", 998); kieSession.insert(fan); kieSession.insert(washer); kieSession.insert(phone); kieSession.fireAllRules(); kieSession.dispose(); }
運行程序依然能獲得相同的結果。
規則文件除了 drl 文件之類,還有其它類型的文件,如 xls, csv。
Drools 官網首頁: https://www.drools.org/
Drools 官方文檔: https://docs.jboss.org/drools/release/7.12.0.Final/drools-docs/html_single/index.html