drools简单应用
Posted jagerlan
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了drools简单应用相关的知识,希望对你有一定的参考价值。
当某个服务的需求经常变的时候,如果使用了硬编码的方式进行开发会是一件非常麻烦的事。
最近在对项目的积分模块进行改造的时候想到了规则引擎,使用规则引擎处理复杂而且多变的业务逻辑有其非常大的优势,包括实时更新、性能等方面。
不多说,直接上代码:
1、第一步先写好工具类,有了工具类,只需在应用的业务场景中调用相应方法就可以了
@Component public class KieSessionUtils { private static KieBase kieBase; //定义规则文件的包名,与drl文件里的package对应 private static final String drlPackage = "rules"; //定义drl文件的存放路径,静态变量需要通过在其set方法上打@Value注解,才可实现配置注入 private static String drlPath; //通过配置拉取路径,这里推荐一下apollo配置中心,使用apollo可以实时更改通过@Value拉取的配置 @Value("${drools.points.drlPath}") public void setDrlPath(String drlPath){ KieSessionUtils.drlPath = drlPath; } /** * 生成kieSeesion会话 * @param ruleName * @return * @throws Exception */ public static KieSession newKieSession(String ruleName) throws Exception { //无状态的kieSession,和有状态相比,区别在于不维持会话,即使用完后自动释放资源,不需要手动调dispose //StatelessKieSession kieSession = getKieBase(ruleName).newStatelessKieSession(); //有状态的kieSession KieSession kieSession = getKieBase(ruleName).newKieSession(); //添加监听器,这里加的是对规则文件运行debug监听器,测试时最好加上,用于排查问题,生产上可视情况去掉 kieSession.addEventListener(new DebugRuleRuntimeEventListener()); return kieSession; } /** * 生成kieBase * @param ruleName 规则文件名 * @return * @throws Exception */ protected static KieBase getKieBase(String ruleName) throws Exception { //判断kieBase和需要获取的规则文件是否存在,不存在则重新初始化kieBase if (kieBase ==null || kieBase.getRule(drlPackage,ruleName)==null) { KieServices kieServices = KieServices.Factory.get(); KieFileSystem kfs = kieServices.newKieFileSystem(); //获取规则数据源,这里由于本人项目使用的是springboot,打包会打成jar包,如果想做实时更新,drl文件需要放在jar包外面 //获取resource的方式很多,不一定要用读取文件的方式,可根据自己的设计和业务场景采取不同方案 Resource resource = kieServices.getResources().newFileSystemResource(new File(drlPath+"/"+ruleName)); resource.setResourceType(ResourceType.DRL); kfs.write(resource); KieBuilder kieBuilder = kieServices.newKieBuilder(kfs).buildAll(); if (kieBuilder.getResults().getMessages(Message.Level.ERROR).size() > 0) { throw new Exception(); } KieContainer kieContainer = kieServices.newKieContainer(kieServices.getRepository().getDefaultReleaseId()); kieBase = kieContainer.getKieBase(); } return kieBase; } /** * 更新规则 * @param ruleName 规则名和规则文件名 * @throws Exception */ public static void refreshRules(String ruleName) throws Exception { //判断规则不为null,则移除规则 if (kieBase !=null && kieBase.getRule(drlPackage,ruleName)!=null){ //为了方便,本人把规则名和drl文件名称统一定义了 kieBase.removeRule(drlPackage,ruleName); //重新初始化kieBase getKieBase(ruleName); } } }
2、编写规则文件,这里只给出和规则引擎格式有关的代码
package rules; //包名 import com.jiuair.dto.AddObject import java.util.List import java.util.HashMap import java.util.Map import java.util.ArrayList import java.util.Date import java.util.Iterator import java.util.Set global com.demo.dto.AddObject addObject //传入的对象,同时也是返回值对象 rule "add.drl" //规则名,为了方便,设为何drl文件名一样,可以不一样 when $s : AddObject(); then 。。。。。//这一段加自己业务代码逻辑,支持jdk $s.setResult(X); //执行完逻辑后将结果设置到对象中 end
3、在业务场景中调用工具类里的方法
private AddObject executeAddRule(Object data) { AddObject addObject = new AddObject(); addObject.setJsonObject(data); try { //获取会话 KieSession kieSession = KieSessionUtils.newKieSession("add.drl"); //设置传入参数 kieSession.insert(addObject); //设置全局参数 kieSession.setGlobal("addObject",addObject); //执行规则 kieSession.fireAllRules(); //释放会话资源 kieSession.dispose(); } catch (Exception e) { e.printStackTrace(); } return addObject; }
4、实现实时更新drl文件
/** * 更新规则文件,这里只给出service层的代码了,相信controller大家都会写。。。 * @param name 名称为drl的文件名 * @param is 由于dubbo不支持流的方式传输,文件需在controller转为byte数组,再传到service */ @Override public void refreshRule(String name, byte[] is) { try { FileOutputStream fos = new FileOutputStream(drlPath+"/"+name); fos.write(is); fos.close(); KieSessionUtils.refreshRules(name); } catch (Exception e) { e.printStackTrace(); } }
附maven引包:
<properties> <runtime.version>7.20.0.Final</runtime.version> </properties> <dependency> <groupId>org.kie</groupId> <artifactId>kie-api</artifactId> <version>${runtime.version}</version> </dependency> <dependency> <groupId>org.kie</groupId> <artifactId>kie-internal</artifactId> <version>${runtime.version}</version> </dependency> <dependency> <groupId>org.drools</groupId> <artifactId>drools-core</artifactId> <version>${runtime.version}</version> </dependency>
没有英汉互译结果
请尝试网页搜索
请尝试网页搜索
以上是关于drools简单应用的主要内容,如果未能解决你的问题,请参考以下文章