1.简述
业务需求总是千变万化,如何把业务需求中的业务规则给抽取出来;如何让技术和决策分开来,规则引擎的动态加载为我们提供了一个方案;drools从6.0版本开始提供动态加载规则,6.4.0.Final版本改变了很多API;
本期的方案将把drools的规则放置到数据库中,并动态生成规则:demo中第一次不命中规则,中间动态增加一个规则文件,第二次再次匹配则命中;
2.代码
核心工具类 :DroolsUtils.java
package com.caicongyang.drools.utils; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.drools.compiler.kie.builder.impl.InternalKieModule; import org.kie.api.KieServices; import org.kie.api.builder.KieBuilder; import org.kie.api.builder.KieFileSystem; import org.kie.api.builder.ReleaseId; import org.kie.api.builder.model.KieBaseModel; import org.kie.api.builder.model.KieModuleModel; import org.kie.api.builder.model.KieSessionModel; import org.kie.api.conf.EqualityBehaviorOption; import org.kie.api.conf.EventProcessingOption; import org.kie.internal.io.ResourceFactory; /** * 动态生成kjar工具类 * @author caicongyang1 * @version id: DroolsUtils, v 0.1 16/10/26 下午1:58 caicongyang1 Exp $$ */ public class DroolsUtils { /** * 默认规则文件所在路径 */ private static final String RULES_PATH = "rules"; /** * 获取规定目录下的规则文件 * * @return * @throws IOException */ private static List<File> getRuleFiles() throws IOException { List<File> list = new ArrayList<File>(); String filePath = Thread.currentThread().getContextClassLoader().getResource("").getPath(); File rootDir = new File(filePath); File[] files = rootDir.listFiles(); for (File itemFile : files) { if (itemFile.isDirectory() && itemFile.getName().equals(RULES_PATH)) { for (File f : itemFile.listFiles()) { if (f.getName().endsWith(".drl")) { list.add(f); } } } } return list; } /** * 初始化一个kjar:把原有的drl包含进新建的kjar中 * * @param ks * @param releaseId * @return * @throws IOException */ public static InternalKieModule initKieJar(KieServices ks, ReleaseId releaseId) throws IOException { KieFileSystem kfs = createKieFileSystemWithKProject(ks, true); kfs.writePomXML(getPom(releaseId)); for (File file : getRuleFiles()) { kfs.write("src/main/resources/" + file.getName(), ResourceFactory.newClassPathResource(RULES_PATH + File.separator + file.getName(), "UTF-8")); } KieBuilder kieBuilder = ks.newKieBuilder(kfs); if (!kieBuilder.buildAll().getResults().getMessages().isEmpty()) { throw new IllegalStateException("Error creating KieBuilder."); } return (InternalKieModule) kieBuilder.getKieModule(); } public static InternalKieModule createKieJar(KieServices ks, ReleaseId releaseId, ResourceWrapper resourceWrapper) { KieFileSystem kfs = createKieFileSystemWithKProject(ks, true); kfs.writePomXML(getPom(releaseId)); kfs.write("src/main/resources/" + resourceWrapper.getTargetResourceName(), resourceWrapper.getResource()); KieBuilder kieBuilder = ks.newKieBuilder(kfs); if (!kieBuilder.getResults().getMessages().isEmpty()) { System.out.println(kieBuilder.getResults().getMessages()); throw new IllegalStateException("Error creating KieBuilder."); } return (InternalKieModule) kieBuilder.getKieModule(); } /** * 创建默认的kbase和stateful的kiesession * * @param ks * @param isdefault * @return */ public static KieFileSystem createKieFileSystemWithKProject(KieServices ks, boolean isdefault) { KieModuleModel kproj = ks.newKieModuleModel(); KieBaseModel kieBaseModel1 = kproj.newKieBaseModel("KBase").setDefault(isdefault) .setEqualsBehavior(EqualityBehaviorOption.EQUALITY).setEventProcessingMode(EventProcessingOption.STREAM); // Configure the KieSession. kieBaseModel1.newKieSessionModel("KSession").setDefault(isdefault) .setType(KieSessionModel.KieSessionType.STATEFUL); KieFileSystem kfs = ks.newKieFileSystem(); kfs.writeKModuleXML(kproj.toXML()); return kfs; } /** * 创建kjar的pom * * @param releaseId * @param dependencies * @return */ public static String getPom(ReleaseId releaseId, ReleaseId... dependencies) { String pom = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<project xmlns=\"http://maven.apache.org/POM/4.0.0\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" + " xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd\">\n" + " <modelVersion>4.0.0</modelVersion>\n" + "\n" + " <groupId>" + releaseId.getGroupId() + "</groupId>\n" + " <artifactId>" + releaseId.getArtifactId() + "</artifactId>\n" + " <version>" + releaseId.getVersion() + "</version>\n" + "\n"; if (dependencies != null && dependencies.length > 0) { pom += "<dependencies>\n"; for (ReleaseId dep : dependencies) { pom += "<dependency>\n"; pom += " <groupId>" + dep.getGroupId() + "</groupId>\n"; pom += " <artifactId>" + dep.getArtifactId() + "</artifactId>\n"; pom += " <version>" + dep.getVersion() + "</version>\n"; pom += "</dependency>\n"; } pom += "</dependencies>\n"; } pom += "</project>"; return pom; } }
资源包装类:ResourceWrapper.java
package com.caicongyang.drools.utils; import org.kie.api.io.Resource; /** * 资源包装类 * @author caicongyang1 * @version id: ResourceWrapper, v 0.1 16/10/26 下午2:15 caicongyang1 Exp $$ */ public class ResourceWrapper { private Resource resource; private String targetResourceName; public ResourceWrapper(Resource resource, String targetResourceName) { this.resource = resource; this.targetResourceName = targetResourceName; } public Resource getResource() { return resource; } public String getTargetResourceName() { return targetResourceName; } public void setResource(Resource resource) { this.resource = resource; } public void setTargetResourceName(String targetResourceName) { this.targetResourceName = targetResourceName; } }
fact类:Message.java
package com.caicongyang.drools.fact; import java.io.Serializable; /** * bean * @author caicongyang1 * @version id: Message, v 0.1 16/10/26 下午2:49 caicongyang1 Exp $$ */ public class Message implements Serializable { private static final long serialVersionUID = 1L; private String status; public String getStatus() { return status; } public void setStatus(String status) { this.status = status; } }
主测试类:dynamicDrlTest.java
package com.caicongyang.drools.test; import org.drools.compiler.kie.builder.impl.InternalKieModule; import org.kie.api.KieServices; import org.kie.api.builder.KieRepository; import org.kie.api.builder.ReleaseId; import org.kie.api.runtime.KieContainer; import org.kie.api.runtime.KieSession; import org.kie.internal.io.ResourceFactory; import com.caicongyang.drools.fact.Message; import com.caicongyang.drools.utils.DroolsUtils; import com.caicongyang.drools.utils.ResourceWrapper; /** * * drools6.4动态加载规则文件:第一次不命中,动态增加规则以后,命中 * * @author caicongyang1 * @version id: dynamicDrlTest, v 0.1 16/10/26 下午2:00 caicongyang1 Exp $$ */ public class dynamicDrlTest { private static final String RULESFILE_NAME = "rules.drl"; /** * 规则文件内容(可以从数据库中加载) */ private static final String rules = "package com.caicongyang.drools.test; import com.caicongyang.drools.fact.Message; rule \"Hello World \" when message:Message (status == \"0\") then System.out.println(\"hello, Drools!\"); end"; public static void main(String[] args) throws Exception { KieServices kieServices = KieServices.Factory.get(); /** * 指定kjar包 */ final ReleaseId releaseId = kieServices.newReleaseId("com", "caicongyang", "1.0.0"); // 创建初始化的kjar InternalKieModule kJar = DroolsUtils.initKieJar(kieServices, releaseId); KieRepository repository = kieServices.getRepository(); repository.addKieModule(kJar); KieContainer kieContainer = kieServices.newKieContainer(releaseId); KieSession session = kieContainer.newKieSession(); Message message = new Message(); message.setStatus("0"); //同一个fact第一次不命中 try { session.insert(message); session.fireAllRules(); } catch (Exception e) { } finally { session.dispose(); } System.out.println("-----first fire end-------"); //新增一个规则文件 kJar = DroolsUtils.createKieJar(kieServices, releaseId, new ResourceWrapper(ResourceFactory.newByteArrayResource(rules.getBytes()), RULESFILE_NAME)); repository.addKieModule(kJar); kieContainer.updateToVersion(releaseId); //同一个fact再次过滤规则:命中 session = kieContainer.newKieSession(); try { session.insert(message); session.fireAllRules(); } catch (Exception e) { } finally { session.dispose(); } System.out.println("-----senond fire end-------"); } }
上一篇:Drools6.4动态加载规则之(一)模板的简单应用 :http://blog.csdn.net/caicongyang/article/details/52702628
更多精彩内容请继续关注我的博客:http://blog.csdn.NET/caicongyang
记录与分享,你我共成长 -fromcaicongyang
相关推荐
### Drools从字符串中动态加载规则 在使用Drools规则引擎时,有时我们需要实现更加灵活的规则管理方式。例如,在开发过程中,我们可能希望不通过每次修改代码或重启服务来更新业务规则,而是能够在运行时动态地更改...
kie drools 6.4是Red Hat公司的业务规则管理系统(BRMS)的一部分,它提供了一个强大的规则引擎,用于处理和执行基于规则的应用程序。在这个配置过程中,我们将关注如何在Windows 10环境下设置kie drools的web应用,...
drools6.4+spring集成是一项将业务规则引擎Drools与Spring框架相结合的技术实践,旨在利用Drools的强大规则处理能力,结合Spring的灵活应用管理,构建高效、可维护的业务系统。在这个项目实例中,我们将深入探讨如何...
接下来,我们需要创建Drools的规则文件(`.drl`),该文件包含了业务规则的定义。例如: ```drl package com.example.rules import com.example.model.MyObject; rule "Example Rule" when $myObject : MyObject...
drools动态生成规则文件是基于Java的业务...掌握drools的动态规则生成机制,有助于构建更加智能和响应迅速的业务系统。在实际应用中,应充分利用drools提供的API和功能,同时关注性能和可维护性,确保系统的稳定运行。
为了将Drools与Spring框架集成,需要配置Spring的Bean来加载规则文件并创建KieSession。可以通过XML配置或Java配置来实现。下面是一个简单的Java配置示例: ```java @Configuration public class DroolsConfig { ...
为了动态加载规则,我们需要编写一个Drools规则服务类。该服务类应包含一个方法,用于从数据库中读取DRL内容,然后使用`KieServices`的`KieFileSystem`、`KieBuilder`和`KieContainer`接口将DRL编译为KieSession。...
在这个"drools5 规则动态加载示例"中,我们将探讨如何在不重启服务的情况下,实现规则的热更新,即动态加载修改后的规则文件,使得业务逻辑能够实时适应变化。 在传统的软件开发中,一旦应用部署,若需更改业务规则...
5. **规则更新**:当你有新的.drl文件时,重复加载和创建`KieSession`的步骤,即可实现规则的动态更新。 ### 四、注意事项 1. **版本控制**:确保在更新规则时,对旧的KieSession进行清理,避免冲突和数据混乱。 ...
如果对drools还不是特别熟悉的,可以看下 《规则引擎Drools 之 初识drools》这篇文章; 本文源码,github 传送门:https://github.com/vincent9309/drools: 系统架构如下: 二、项目目录结构 三、...
动态规则意味着在程序运行过程中,可以根据需求从外部源(例如数据库)动态地加载、修改或删除规则。这种方式特别适合那些需要频繁调整规则或者规则变化不可预见的项目。例如,银行可能会根据市场条件实时调整贷款...
drools整合apollo实现动态规则引擎,可以在不停服的情况下动态调整规则。无需数据库等存储,自动推送
- **加载规则**:Drools通过KieServices读取.drl文件(规则定义文件)并将规则加载到KieContainer中。 - **创建KieSession**:从KieContainer创建一个KieSession实例,它是规则执行的上下文。 - **插入事实**:将...
标签“drools 动态模板”暗示了这个示例关注的是如何利用Drools进行动态规则管理,以及如何在SpringBoot环境中实现这一功能。通过这种方式,开发者可以快速响应业务变化,提高系统的可维护性和灵活性。 至于文件名`...
1. **KieContainer**:在运行时,我们需要创建`KieContainer`实例来加载规则和规则流。 2. **KieSession**:通过`KieContainer`获取`KieSession`,`KieSession`是执行规则和规则流的接口。 3. **启动流程**:调用`...
Drools 规则引擎文档教程 Drools 规则引擎是一种基于 Java 的开源规则引擎,主要用来解决复杂的业务逻辑问题。下面是 Drools 规则引擎在在线申请信用卡业务场景中的应用。 问题引出现有一个在线申请信用卡的业务...
Drools5.x 是一款基于 Java 的开源规则引擎,它允许开发者在业务逻辑层中使用基于规则的编程方法来构建灵活、可管理的业务规则。规则引擎作为一种软件组件,专门用于根据一组定义好的规则来处理业务逻辑。Drools5.x ...
KieContainer则用于加载和管理规则库,它可以在运行时动态更新规则,以应对业务需求的变化。 此外,规则源码是Drools应用的另一个关键部分。这些源码通常以DRL文件形式存在,包含了所有业务规则的定义。通过DRL,...
5. 使用Drools API来加载规则、创建工作内存并触发规则执行。 总之,"drools 最小依赖jar包集合"是一个优化过的Drools运行环境,减少了不必要的依赖,提高了项目效率。开发者应仔细评估和使用这个集合,以实现高效...