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(); } }