drools網上資料很多,這裏針對自己的接觸瞭解和實際應用進行如下總結,
- 工程引入。
工程pom.xml,至少需加入<dependency> <groupId>org.kie</groupId> <artifactId>kie-api</artifactId> <version>6.5.0.Final</version> </dependency> <dependency> <groupId>org.drools</groupId> <artifactId>drools-compiler</artifactId> <version>6.5.0.Final</version> </dependency>
從官網下包,例如:drools-distribution-6.5.0.Final,從binaries目錄,大致需手工引入第三方包:
ant-1.8.3.jar
core-3.1.1.jar
ecj-4.4.2.jar
……
忘了還有哪些,這些是運行時用到,所以在實際使用時,可以依據報錯信息(java.lang.ClassNotFoundException),反推還需要哪些jar,反正所需要的都在binaries目錄裏。 - 簡單封裝。
package com.pomelo.drools.util;
import java.util.ArrayList;
import java.util.List;
import org.kie.api.KieServices;
import org.kie.api.builder.KieBuilder;
import org.kie.api.builder.KieFileSystem;
import org.kie.api.builder.KieRepository;
import org.kie.api.builder.Message;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.rule.AgendaFilter;
import org.kie.api.runtime.rule.Match;
import com.pomelo.drools.model.RuleCfg;
/**
* @author zxz
*
*/
public class MyDrools {
/**
* 對GKS、GKR、GKFS這三個的概念模棱兩可,大概一個應用構建一套就OK了。
*/
private static final KieServices GKS = KieServices.Factory.get();
private static final KieRepository GKR = GKS.getRepository();
private static final KieFileSystem GKFS = GKS.newKieFileSystem();
/**
* 用於本地應用標記哪個規則文件已加載。
*/
private static List<string> gKfsFacade = new ArrayList<string>();
/**
* 用於存放已加載規則的容器,每次加載規則需重新生成。
*/
private static KieContainer kc;
/**
* 規則配置,一般存在數據庫中,這裏用靜態語句塊初始化。
*/
private static RuleCfg ruleCfg;
static {
StringBuffer sb = new StringBuffer("package com.pomelo.drools.drl;\n");
sb.append("import com.pomelo.drools.model.Users\n");
sb.append("rule \"userStatusChangeRule\"\n");
sb.append("when\n");
sb.append("users:Users(status == 0)\n");
sb.append("then\n");
sb.append("users.status = 1;\n");
sb.append("System.out.println(\"done\");\n");
sb.append("end;\n");
ruleCfg = new RuleCfg();
ruleCfg.setRuleId(2000001);
ruleCfg.setClassify("user_status_change");
ruleCfg.setRuleName("userStatusChangeRule");
ruleCfg.setRule(sb.toString());
ruleCfg.setStatus(0);
}
/**
* ruleId:規則編碼,例如:2000001。
* params:規則判斷所需要的參數。
*/
public static void invokeIns(final int ruleId, Object... params) {
/**
* loadCfg:根據規則編碼查詢規則對象,實際應用是查詢數據庫,這裏簡化不做說明。
*/
RuleCfg ruleCfg = loadCfg(ruleId);
/**
* 生成規則文件存放路徑,這裏可以大致推測drool部分核心內容,是把規則寫在drl文件,drools內部自己構建一個文件系統。
*/
String drlPath = genDrlPath(ruleCfg);
if(ruleCfg.getStatus() == RuleCfg.STATUS_INIT)
gKfsFacade.remove(drlPath);
if(!gKfsFacade.contains(drlPath)) {
synchronized(gKfsFacade) {
if(!gKfsFacade.contains(drlPath)) {
GKFS.write(drlPath, ruleCfg.getRule());
KieBuilder kb = GKS.newKieBuilder(GKFS);
/**
* 類似java工程,對文件系統進行編譯。
*/
kb.buildAll();
if(kb.getResults().hasMessages(Message.Level.ERROR)) {
System.out.println(kb.getResults().toString());
/**
* 若編譯失敗,則把當前規則從文件系統中刪除掉,重新編譯。
*/
GKFS.delete(ruleCfg.getClassify());
kb = GKS.newKieBuilder(GKFS);
kb.buildAll();
kc = GKS.newKieContainer(GKR.getDefaultReleaseId());
throw new RuntimeException("Build Errors:\n" + kb.getResults().toString());
}
kc = GKS.newKieContainer(GKR.getDefaultReleaseId());
ruleCfg.setStatus(RuleCfg.STATUS_LOADED);
gKfsFacade.add(drlPath);
}
}
}
fireTheRule(ruleCfg.getRuleName(), params);
}
private static RuleCfg loadCfg(final int ruleId) {
return ruleCfg;
}
private static String genDrlPath(RuleCfg ruleCfg) {
return "src/main/resources/drl/" + ruleCfg.getClassify() + "/" + ruleCfg.getRuleName() + ".drl";
}
private static void fireTheRule(String ruleName, Object... params) {
KieSession ks = kc.newKieSession();
try {
for(int i = 0;i < params.length;i++) {
ks.insert(params[i]);
}
ks.fireAllRules(ruleNameEqualsAgendaFilter(ruleName));
} finally {
ks.dispose();
}
}
private static AgendaFilter ruleNameEqualsAgendaFilter(final String ruleName) {
return new AgendaFilter() {
public boolean accept(Match paramMatch) {
return paramMatch.getRule().getName().equals(ruleName);
}
};
}
}
完整工程,詳見https://github.com/Monicazxz/MyDrools