drools簡介:
規則引擎是一種嵌入在應用程序中的組件,實現了將業務決策從應用程序代碼中分離出來,並使用預定義的語義模塊編寫業務決策。接受數據輸入,解釋業務規則,並根據業務規則做出業務決策。
Drools實現了規則引擎,它是一個業務邏輯集成平台,基於JAVA和RATE算法的產生式規則引擎實現,是Red Hat旗下的開源產品
kieServices: KieServices 是一個線程安全的單例,是訪問規則引擎其他服務的中心
KieModule: kieModule時一個標准的Maven工程,包含了pom.xml、kmodule.xml和規則引擎必備資源
KieContainer: KieModule、以及子KieModule所有知識庫的容器
KieSession: 用於與規則引擎進行交互的會話
KieSession: 有狀態的會話
StatelessKieSession: 無狀態的會話
- 引入maven依賴
<!--drools 依賴-->
<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>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-core</artifactId>
<version>6.5.0.Final</version>
</dependency>
2. 加載規則
本例中在項目啟動時進行規則引擎的初始化
初始化步驟:
1.獲取KieService 用於訪問規則引擎其他接口
2.加載規則drl文件
3.KieContainer 容器進而獲取KieSession
@Configuration
public class DroolsAutoConfiguration {
/**
* 加載項目中的drl文件路徑
*/
// @Bean
// public Map<String, KieSession> getMapKieSession() throws IOException {
// Map<String, KieSession> kieSessionMap = new HashMap<String, KieSession>();
// for (DroolsEnum path : DroolsEnum.values()) {
// KieServices kieServices = KieServices.Factory.get();
// KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
// ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
// Resource[] resource = resourcePatternResolver.getResources("classpath*:" + path.getRulesPath() + "/*.*");
// for (Resource file : resource) {
// org.kie.api.io.Resource resource1 = ResourceFactory.newClassPathResource(path.getRulesPath() + "/" + file.getFilename(), "UTF-8");
// kieFileSystem.write(resource1);
// }
// final KieRepository kieRepository = kieServices.getRepository();
// kieRepository.addKieModule(new KieModule() {
// @Override
// public ReleaseId getReleaseId() {
// return kieRepository.getDefaultReleaseId();
// }
// });
// KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem);
// kieBuilder.buildAll();
// KieContainer kieContainer = kieServices.newKieContainer(kieRepository.getDefaultReleaseId());
// KieSession kieSession = kieContainer.newKieSession();
// kieSessionMap.put(path.getName(), kieSession);
// }
// return kieSessionMap;
// }
/**
* 啟動加載絕對路徑上所有的drl文件
* @return
* @throws IOException
*/
@Bean
public KieSession getMapKieSession() throws IOException {
KieServices kieServices = KieServices.Factory.get();
KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
//讀取配置文件獲取drl.path
Properties properties = new Properties();
FileInputStream fileInputStream = new FileInputStream("src/main/resources/conf/drl.properties");
properties.load(fileInputStream);
String drlPath = properties.getProperty("drl.path");
//判斷路徑上是否存在文件夾,如果不存在則自動創建
File file1 = new File(drlPath);
if (!file1.isDirectory()){
file1.mkdir();
}
File[] files = file1.listFiles();
for (File file : files) {
kieFileSystem.write(ResourceFactory.newFileResource(file));
}
KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem).buildAll();
KieContainer kieContainer = kieServices.newKieContainer(kieServices.getRepository().getDefaultReleaseId());
SessionConfiguration conf = SessionConfiguration.getDefaultInstance();
KieSession kieSession = kieContainer.newKieSession(conf);
return kieSession;
}
}
當然也可以將初始化規則引擎的操作通過接口來完成,或者將規則保存到數據庫中實現動態的加載規則
3.編寫規則文件
規則文件是以 .drl 為后綴的文件名
package drl
import com.aliyun.aiassistant.bean.QuestionInfoBean
import javafx.beans.binding.When
rule "one" -----規則名
no-loop true -----執行一次后,是否能被再次激活
lock-on-active true -----可以避免其他規則修改FACT對象導致規則的重新執行
salience 1 -----執行優先級
when
$s : QuestionInfoBean(lastStep == "輕瓦斯報警信號次數" && Integer.parseInt(choseOption) >= 2)
----規則條件 QuestionInfoBean: 自定義的Bean對象 $S : QuestionInfoBean 將QuestionInfoBean 映射到 $s
then
------ 設置返回值
$s.setLastStep("申請變壓器停運並申請聯系檢修002");
$s.setFlag(true);
----- 觸發
update($s)
end
rule "two"
no-loop true
lock-on-active true
salience 1
when
$s : QuestionInfoBean(lastStep == "輕瓦斯報警信號次數" && Integer.parseInt(choseOption) < 2)
then
$s.setLastStep("yyyccccycycyyyc002");
$s.setOptions(new Object[]{true,false});
update($s)
end
4. 調用規則引擎
public synchronized static void executeRule(KieSession kieSession, QuestionInfoBean questionInfoBean) {
if (questionInfoBean != null) {
kieSession.insert(questionInfoBean);
int count = kieSession.fireAllRules();
}
}
