
在上一篇文章中我们在eclipse中安装了drools插件和runtimes在这篇文章中我们写一个简单的示例。一、引入依赖包properties .....其他的jar包配置 !-- drools版本 -- drools.version7.15.0.Final/drools.version /properties !-- drools begin -- dependency groupIdorg.drools/groupId artifactIddrools-core/artifactId version${drools.version}/version /dependency dependency groupIdorg.drools/groupId artifactIddrools-compiler/artifactId version${drools.version}/version /dependency dependency groupIdorg.drools/groupId artifactIddrools-decisiontables/artifactId version${drools.version}/version /dependency dependency groupIdorg.drools/groupId artifactIddrools-templates/artifactId version${drools.version}/version /dependency dependency groupIdorg.kie/groupId artifactIdkie-api/artifactId version${drools.version}/version /dependency dependency groupIdorg.kie/groupId artifactIdkie-internal/artifactId version${drools.version}/version /dependency dependency groupIdorg.eclipse.jdt/groupId artifactIdcore/artifactId version3.3.0-v_771/version /dependency !-- drools end --注意如果不引入org.eclipse.jdt的这个jar包会在运行的时候报The Eclipse JDT Core jar is not in the classpath二、加入配置文件在src/main/resources/META-INF文件夹下加入kmodule.xml配置文件?xml version1.0 encodingUTF-8? kmodule xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xmlnshttp://www.drools.org/xsd/kmodule kbase namerules packagesdrools ksession nameall-rules/ /kbase /kmodulekbase的属性设置Attribute nameDefault valueAdmitted valuesMeaningnamenoneany从KieContainer中获取KieBase的nameincludesnone逗号分隔列表逗号分隔的列表kmodule中定义的其他kbase都将包含在该中packagesallany comma separated list该packages下所有的资源文件都将包含在该kbase中defaultfalsetrue, false定义该kbase是否是默认的若是默认的则从KieContainer中可以不传name直接创建最多只能有一个默认kbaseequalsBehavioridentityidentity, equality定义当新fact插入working memory时drools的行为。 使用identity 则总是创建一个新的FactHandle除非同样的对象在workingmemory中不存在。 使用equality 则只有心插入的对象不同于根据其提供的equal方法比较已经存在的fact才创建。eventProcessingModecloudcloud, stream当以cloud模式创建时事件被认为是一般的facts。 当stream时允许进行时间推理declarativeAgendadisableddisabled, enabled是否启用Declarative Agendaksession的属性设置属性名默认值合法的值描述namenoneanyKieSession的名称该值必须唯一也是强制的必须设置。KIESession的唯一名称标识。用于从KieContainer中获取KieSession。typestatefulstateful, stateless定义该session到底是有状态stateful的还是无状态stateless的有状态的session可以利用Working Memory执行多次而无状态的则只能执行一次。defaultfalsetrue, false定义该session是否是默认的如果是默认的话则可以不用通过session的name来创建session在同一个module中最多只能有一个默认的session。clockTyperealtimerealtime, pseudo定义时钟类型用在事件处理上面在复合事件处理上会用到其中realtime表示用的是系统时钟而pseudo则是用在单元测试时模拟用的。暂时不用理会。定义事件时间戳是由系统时钟还是由应用程序控制的伪时钟确定的。 该时钟对于单元测试时间规则特别有用。beliefSystemsimplesimple, jtms, defeasible定义KieSession使用的信任系统的类型。至于为啥要放在这个路径下可以通过看源码得知如下图KieModuleModel实现类是KieModuleModelImplKieBaseModel实现类是KieBaseModelImplKieSessionModel实现类是KieSessionModelImplKieContainer实现类是 KieContainerImplKieServices实现类是KieServicesImpl该类是一个静态方法有一个内部类Factory用于生成KieServices并且KieServices是单例模式。public interface KieServices { ………………………………省略其他的代码…………………………………………………… /** * Returns a reference to the KieServices singleton */ static KieServices get() { return Factory.get(); } /** * A Factory for this KieServices */ class Factory { private static class LazyHolder { private static KieServices INSTANCE ServiceRegistry.getInstance().get(KieServices.class); } /** * Returns a reference to the KieServices singleton */ public static KieServices get() { return LazyHolder.INSTANCE; } }在ClasspathKieProject类中会根据kmodule.xml文件的定义将其解析并生成成KieModuleModel、KieBaseModel、KieSessionModel对象。在运行时KieContainer会根据*Model对象来创建KieModule、KieBase、KieSession对象。其中KieModule和KieBase只会创建一次而KieSession则有可能创建多次因为KieSession的创建成本很低同时KieSession包含了运行时的数据所以可以销毁、创建若干次。三、定义实体类和规则文件我们以客户购买东西打折为例年龄大于60的购买金额超过100元打9折年龄小于等于60的购买金额超过100元打95折package com.drools7.model; public class Customer { private String name; private int age; public Customer(String name, int age) { this.name name; this.age age; } public String getName() { return name; } public int getAge() { return age; } public void setAge(int age) { this.age age; } public void setName(String name) { this.name name; } }package com.drools7.model; public class Discount { // 打折默认100即不打折 private int discount 100; // 用户 private Customer customer; // 购买的总金额 private int amount 100; public int getDiscount() { return discount; } public void setDiscount(int discount) { this.discount discount; } public Customer getCustomer() { return customer; } public void setCustomer(Customer customer) { this.customer customer; } public int getAmount() { return amount; } public void setAmount(int amount) { this.amount amount; } }写规则文件package drools import com.drools7.model.Discount; rule customer-discount1 when $discount : Discount(customer.age 60 amount 100) then $discount.setDiscount(90); end rule customer-discount2 when $discount : Discount(customer.age 60 amount 100) then $discount.setDiscount(95); end编写测试类并运行package com.drools7.model; import org.junit.Test; import org.kie.api.KieServices; import org.kie.api.runtime.KieContainer; import org.kie.api.runtime.KieSession; public class Demo { Test public void test() { KieServices kieServices KieServices.Factory.get(); // 默认自动加载 META-INF/kmodule.xml KieContainer kieContainer kieServices.getKieClasspathContainer(); // kmodule.xml 中定义的 ksession name,默认是以有状态的会话来生成KieSession KieSession kieSession kieContainer.newKieSession(all-rules); // new一组事实数据 Customer customer new Customer(Anna, 29); Discount discount new Discount(); discount.setCustomer(customer); discount.setAmount(100); /** * 与有状态会话进行交互的方式是br/ * 我们将一组事实数据插入其中执行任何激活的规则然后提取我们正在寻找的响应 */ // 将一组事实数据插入其中 kieSession.insert(discount); // 执行激活的规则 int count kieSession.fireAllRules(); System.out.println(count); System.out.println(discount.getDiscount()); // After the application finishes using the session, though, it must call the // dispose() method in order to free the resources and used memory. // 但是在应用程序完成使用会话之后它必须调用dispose方法以释放资源和使用的内存 kieSession.dispose(); } }运行结果如下可以看到执行了一条规则事实数据执行后打折是95[DEBUG] 2019-09-01 11:39:14,646 org.drools.core.common.DefaultAgenda - State was INACTIVE is now FIRING_ALL_RULES [DEBUG] 2019-09-01 11:39:14,752 org.drools.core.common.DefaultAgenda - State was FIRING_ALL_RULES is now HALTING [DEBUG] 2019-09-01 11:39:14,754 org.drools.core.common.DefaultAgenda - State was HALTING is now INACTIVE 1 95 [DEBUG] 2019-09-01 11:39:14,759 org.drools.core.common.DefaultAgenda - State was INACTIVE is now DISPOSED整个目录如下图