[Drools]JAVA规则引擎 -- Drools

Drools规则引擎 Drools(Drools Rule Engine)是一个开源的规则引擎,它主要用于在Java应用程序中实现规则管理。Drools规则引擎将规则定义和管理从应用程序代码中分离出来,使得规则可以独立于应用程序运行。这样可以提高规则的可靠性和可维护性,同时也可以使得规则的更新和管理更加方便。将规则定义和管理从应用程序代码中分离出来,使得规则可以独立于应用程序运行。提供基于规则的访问和操作数据的功能,例如过滤、排序、检索等。支持动态规则扩展和维护,可以根据需要添加、删除或修改规则。 阅读详情

Drools是一个基于Java的规则引擎,开源的,可以将复杂多变的规则从硬编码中解放出来,以规则脚本的形式存放在文件中,使得规则的变更不需要修正代码重启机器就可以立即在线上环境生效。

 本文所使用的demo已上传 http://download.youkuaiyun.com/source/3002213

1、Drools语法

开始语法之前首先要了解一下drools的基本工作过程,通常而言我们使用一个接口来做事情,首先要穿进去参数,其次要获取到接口的实现执行完毕后的结果,而drools也是一样的,我们需要传递进去数据,用于规则的检查,调用外部接口,同时还可能需要获取到规则执行完毕后得到的结果。在drools中,这个传递数据进去的对象,术语叫 Fact对象。Fact对象是一个普通的Java bean,规则中可以对当前的对象进行任何的读写操作,调用该对象提供的方法,当一个java bean插入到workingMemory中,规则使用的是原有对象的引用,规则通过对fact对象的读写,实现对应用数据的读写,对于其中的属性,需要提供getter setter访问器,规则中,可以动态的往当前workingMemory中插入删除新的fact对象。

规则文件可以使用 .drl文件,也可以是xml文件,这里我们使用drl文件。

规则语法:

package:对一个规则文件而言,package是必须定义的,必须放在规则文件第一行。特别的是,package的名字是随意的,不必必须对应物理路径,跟java的package的概念不同,这里只是逻辑上的一种区分。同样的package下定义的function和query等可以直接使用。

比如:package com.drools.demo.point

import:导入规则文件需要使用到的外部变量,这里的使用方法跟java相同,但是不同于java的是,这里的import导入的不仅仅可以是一个类,也可以是这个类中的某一个可访问的静态方法。

比如:

import com.drools.demo.point.PointDomain;

import com.drools.demo.point.PointDomain.getById;

rule:定义一个规则。rule "ruleName"。一个规则可以包含三个部分:

属性部分:定义当前规则执行的一些属性等,比如是否可被重复执行、过期时间、生效时间等。

条件部分,即LHS,定义当前规则的条件,如  when Message(); 判断当前workingMemory中是否存在Message对象。

结果部分,即RHS,这里可以写普通java代码,即当前规则条件满足后执行的操作,可以直接调用Fact对象的方法来操作应用。

规则事例:

rule "name"

       no-loop true

       when

               $message:Message(status == 0)

       then

               System.out.println("fit");

               $message.setStatus(1);

               update($message);

end

上述的属性中:

no-loop : 定义当前的规则是否不允许多次循环执行,默认是false,也就是当前的规则只要满足条件,可以无限次执行。什么情况下会出现一条规则执行过一次又被多次重复执行呢?drools提供了一些api,可以对当前传入workingMemory中的Fact对象进行修改或者个数的增减,比如上述的update方法,就是将当前的workingMemory中的Message类型的Fact对象进行属性更新,这种操作会触发规则的重新匹配执行,可以理解为Fact对象更新了,所以规则需要重新匹配一遍,那么疑问是之前规则执行过并且修改过的那些Fact对象的属性的数据会不会被重置?结果是不会,已经修改过了就不会被重置,update之后,之前的修改都会生效。当然对Fact对象数据的修改并不是一定需要调用update才可以生效,简单的使用set方法设置就可以完成,这里类似于java的引用调用,所以何时使用update是一个需要仔细考虑的问题,一旦不慎,极有可能会造成规则的死循环。上述的no-loop true,即设置当前的规则,只执行一次,如果本身的RHS部分有update等触发规则重新执行的操作,也不要再次执行当前规则。

但是其他的规则会被重新执行,岂不是也会有可能造成多次重复执行,数据紊乱甚至死循环?答案是使用其他的标签限制,也是可以控制的:lock-on-active true

lock-on-active true:通过这个标签,可以控制当前的规则只会被执行一次,因为一个规则的重复执行不一定是本身触发的,也可能是其他规则触发的,所以这个是no-loop的加强版。当然该标签正规的用法会有其他的标签的配合,后续提及。

date-expires:设置规则的过期时间,默认的时间格式:“日-月-年”,中英文格式相同,但是写法要用各自对应的语言,比如中文:"29-七月-2010",但是还是推荐使用更为精确和习惯的格式,这需要手动在java代码中设置当前系统的时间格式,后续提及。属性用法举例:date-expires "2011-01-31 23:59:59" // 这里我们使用了更为习惯的时间格式

date-effective:设置规则的生效时间,时间格式同上。

duration:规则定时,duration 3000   3秒后执行规则

salience:优先级,数值越大越先执行,这个可以控制规则的执行顺序。

其他的属性可以参照相关的api文档查看具体用法,此处略。

 

规则的条件部分,即LHS部分:

when:规则条件开始。条件可以单个,也可以多个,多个条件一次排列,比如

 when

         eval(true)

         $customer:Customer()

         $message:Message(status==0)

上述罗列了三个条件,当前规则只有在这三个条件都匹配的时候才会执行RHS部分,三个条件中第一个

eval(true):是一个默认的api,true 无条件执行,类似于 while(true)

$message:Message(status==0) 这句话标示的:当前的workingMemory存在Message类型并且status属性的值为0的Fact对象,这个对象通常是通过外部java代码插入或者自己在前面已经执行的规则的RHS部分中insert进去的。

前面的$message代表着当前条件的引用变量,在后续的条件部分和RHS部分中,可以使用当前的变量去引用符合条件的FACT对象,修改属性或者调用方法等。可选,如果不需要使用,则可以不写。

条件可以有组合,比如:

Message(status==0 || (status > 1 && status <=100))

RHS中对Fact对象private属性的操作必须使用getter和setter方法,而RHS中则必须要直接用.的方法去使用,比如

   order:Order(name=="qu") order:Order(name=="qu")message:Message(status==0 && orders contains order &&order &&order.name=="qu")

特别的是,如果条件全部是 &&关系,可以使用“,”来替代,但是两者不能混用

如果现在Fact对象中有一个List,需要判断条件,如何判断呢?

看一个例子:

Message {

        int status;

        List<String> names;

}

$message:Message(status==0 && names contains "网易" && names.size >= 1)

上述的条件中,status必须是0,并且names列表中含有“网易”并且列表长度大于等于1

contains:对比是否包含操作,操作的被包含目标可以是一个复杂对象也可以是一个简单的值。 

Drools提供了十二中类型比较操作符:

>  >=  <  <=  ==  !=  contains / not contains / memberOf / not memberOf /matches/ not matches

not contains:与contains相反。

memberOf:判断某个Fact属性值是否在某个集合中,与contains不同的是他被比较的对象是一个集合,而contains被比较的对象是单个值或者对象。

not memberOf:正好相反。

matches:正则表达式匹配,与java不同的是,不用考虑'/'的转义问题

not matches:正好相反。

 

规则的结果部分

当规则条件满足,则进入规则结果部分执行,结果部分可以是纯java代码,比如:

then

       System.out.println("OK"); //会在控制台打印出ok

end

当然也可以调用Fact的方法,比如  $message.execute();操作数据库等等一切操作。

结果部分也有drools提供的方法:

insert:往当前workingMemory中插入一个新的Fact对象,会触发规则的再次执行,除非使用no-loop限定;

update:更新

modify:修改,与update语法不同,结果都是更新操作

retract:删除

RHS部分除了调用Drools提供的api和Fact对象的方法,也可以调用规则文件中定义的方法,方法的定义使用 function 关键字

function void console {

   System.out.println();

   StringUtils.getId();// 调用外部静态方法,StringUtils必须使用import导入,getId()必须是静态方法

}

Drools还有一个可以定义类的关键字:

declare 可以再规则文件中定义一个class,使用起来跟普通java对象相似,你可以在RHS部分中new一个并且使用getter和setter方法去操作其属性。

declare Address
 @author(quzishen) // 元数据,仅用于描述信息

 @createTime(2011-1-24)
 city : String @maxLengh(100)
 postno : int
end

上述的'@'是什么呢?是元数据定义,用于描述数据的数据~,没什么执行含义

你可以在RHS部分中使用Address address = new Address()的方法来定义一个对象。

 

更多的规则语法,可以参考其他互联网资料,推荐:

http://wenku.baidu.com/view/a6516373f242336c1eb95e7c.html

(写的很基础,但是部分语法写的有些简单,含糊不好理解)

2、Drools应用实例:

现在我们模拟一个应用场景:网站伴随业务产生而进行的积分发放操作。比如支付宝信用卡还款奖励积分等。

发放积分可能伴随不同的运营策略和季节性调整,发放数目和规则完全不同,如果使用硬编码的方式去伴随业务调整而修改,代码的修改、管理、优化、测试、上线将是一件非常麻烦的事情,所以,将发放规则部分提取出来,交给Drools管理,可以极大程度的解决这个问题。

(注意一点的是,并非所有的规则相关内容都建议使用Drools,这其中要考虑系统会运行多久,规则变更频率等一系列条件,如果你的系统只会在线上运行一周,那根本没必要选择Drools来加重你的开发成本,java硬编码的方式则将是首选)

我们定义一下发放规则:

积分的发放参考因素有:交易笔数、交易金额数目、信用卡还款次数、生日特别优惠等。

定义规则:

// 过生日,则加10分,并且将当月交易比数翻倍后再计算积分

// 2011-01-08 - 2011-08-08每月信用卡还款3次以上,每满3笔赠送30分

// 当月购物总金额100以上,每100元赠送10分

// 当月购物次数5次以上,每五次赠送50分

// 特别的,如果全部满足了要求,则额外奖励100分

// 发生退货,扣减10分

// 退货金额大于100,扣减100分

在事先分析过程中,我们需要全面的考虑对于积分所需要的因素,以此整理抽象Fact对象,通过上述的假设条件,我们假设积分计算对象如下:

 

  1. /** 
  2.  * 积分计算对象 
  3.  * @author quzishen 
  4.  */  
  5. public class PointDomain {  
  6.     // 用户名  
  7.     private String userName;  
  8.     // 是否当日生日  
  9.     private boolean birthDay;  
  10.     // 增加积分数目  
  11.     private long point;  
  12.     // 当月购物次数  
  13.     private int buyNums;  
  14.     // 当月退货次数  
  15.     private int backNums;  
  16.     // 当月购物总金额  
  17.     private double buyMoney;  
  18.     // 当月退货总金额  
  19.     private double backMondy;  
  20.     // 当月信用卡还款次数  
  21.     private int billThisMonth;  
  22.       
  23.     /** 
  24.      * 记录积分发送流水,防止重复发放 
  25.      * @param userName 用户名 
  26.      * @param type 积分发放类型 
  27.      */  
  28.     public void recordPointLog(String userName, String type){  
  29.         System.out.println("增加对"+userName+"的类型为"+type+"的积分操作记录.");  
  30.     }  
  31.   
  32.     public String getUserName() {  
  33.         return userName;  
  34.     }  
  35. // 其他getter setter方法省略  
  36. }  

 

定义积分规则接口

 

  1. /** 
  2.  * 规则接口 
  3.  * @author quzishen 
  4.  */  
  5. public interface PointRuleEngine {  
  6.       
  7.     /** 
  8.      * 初始化规则引擎 
  9.      */  
  10.     public void initEngine();  
  11.       
  12.     /** 
  13.      * 刷新规则引擎中的规则 
  14.      */  
  15.     public void refreshEnginRule();  
  16.       
  17.     /** 
  18.      * 执行规则引擎 
  19.      * @param pointDomain 积分Fact 
  20.      */  
  21.     public void executeRuleEngine(final PointDomain pointDomain);  
  22. }  

 

规则接口实现,Drools的API很简单,可以参考相关API文档查看具体用法:

 

  1. import java.io.File;  
  2. import java.io.FileNotFoundException;  
  3. import java.io.FileReader;  
  4. import java.io.IOException;  
  5. import java.io.Reader;  
  6. import java.util.ArrayList;  
  7. import java.util.List;  
  8.   
  9. import org.drools.RuleBase;  
  10. import org.drools.StatefulSession;  
  11. import org.drools.compiler.DroolsParserException;  
  12. import org.drools.compiler.PackageBuilder;  
  13. import org.drools.spi.Activation;  
  14.   
  15. /** 
  16.  * 规则接口实现类 
  17.  * @author quzishen 
  18.  */  
  19. public class PointRuleEngineImpl implements PointRuleEngine {  
  20.     private RuleBase ruleBase;  
  21.   
  22.     /* (non-Javadoc) 
  23.      * @see com.drools.demo.point.PointRuleEngine#initEngine() 
  24.      */  
  25.     public void initEngine() {  
  26.         // 设置时间格式  
  27.         System.setProperty("drools.dateformat", "yyyy-MM-dd HH:mm:ss");  
  28.         ruleBase = RuleBaseFacatory.getRuleBase();  
  29.         try {  
  30.             PackageBuilder backageBuilder = getPackageBuilderFromDrlFile();  
  31.             ruleBase.addPackages(backageBuilder.getPackages());  
  32.         } catch (DroolsParserException e) {  
  33.             e.printStackTrace();  
  34.         } catch (IOException e) {  
  35.             e.printStackTrace();  
  36.         } catch (Exception e) {  
  37.             e.printStackTrace();  
  38.         }  
  39.     }  
  40.       
  41.     /* (non-Javadoc) 
  42.      * @see com.drools.demo.point.PointRuleEngine#refreshEnginRule() 
  43.      */  
  44.     public void refreshEnginRule() {  
  45.         ruleBase = RuleBaseFacatory.getRuleBase();  
  46.         org.drools.rule.Package[] packages = ruleBase.getPackages();  
  47.         for(org.drools.rule.Package pg : packages) {  
  48.             ruleBase.removePackage(pg.getName());  
  49.         }  
  50.           
  51.         initEngine();  
  52.     }  
  53.   
  54.     /* (non-Javadoc) 
  55.      * @see com.drools.demo.point.PointRuleEngine#executeRuleEngine(com.drools.demo.point.PointDomain) 
  56.      */  
  57.     public void executeRuleEngine(final PointDomain pointDomain) {  
  58.         if(null == ruleBase.getPackages() || 0 == ruleBase.getPackages().length) {  
  59.             return;  
  60.         }  
  61.           
  62.         StatefulSession statefulSession = ruleBase.newStatefulSession();  
  63.         statefulSession.insert(pointDomain);  
  64.           
  65.         // fire  
  66.         statefulSession.fireAllRules(new org.drools.spi.AgendaFilter() {  
  67.             public boolean accept(Activation activation) {  
  68.                 return !activation.getRule().getName().contains("_test");  
  69.             }  
  70.         });  
  71.           
  72.         statefulSession.dispose();  
  73.     }  
  74.   
  75.     /** 
  76.      * 从Drl规则文件中读取规则 
  77.      * @return 
  78.      * @throws Exception 
  79.      */  
  80.     private PackageBuilder getPackageBuilderFromDrlFile() throws Exception {  
  81.         // 获取测试脚本文件  
  82.         List<String> drlFilePath = getTestDrlFile();  
  83.         // 装载测试脚本文件  
  84.         List<Reader> readers = readRuleFromDrlFile(drlFilePath);  
  85.   
  86.         PackageBuilder backageBuilder = new PackageBuilder();  
  87.         for (Reader r : readers) {  
  88.             backageBuilder.addPackageFromDrl(r);  
  89.         }  
  90.           
  91.         // 检查脚本是否有问题  
  92.         if(backageBuilder.hasErrors()) {  
  93.             throw new Exception(backageBuilder.getErrors().toString());  
  94.         }  
  95.           
  96.         return backageBuilder;  
  97.     }  
  98.   
  99.     /** 
  100.      * @param drlFilePath 脚本文件路径 
  101.      * @return 
  102.      * @throws FileNotFoundException 
  103.      */  
  104.     private List<Reader> readRuleFromDrlFile(List<String> drlFilePath) throws FileNotFoundException {  
  105.         if (null == drlFilePath || 0 == drlFilePath.size()) {  
  106.             return null;  
  107.         }  
  108.   
  109.         List<Reader> readers = new ArrayList<Reader>();  
  110.   
  111.         for (String ruleFilePath : drlFilePath) {  
  112.             readers.add(new FileReader(new File(ruleFilePath)));  
  113.         }  
  114.   
  115.         return readers;  
  116.     }  
  117.   
  118.     /** 
  119.      * 获取测试规则文件 
  120.      *  
  121.      * @return 
  122.      */  
  123.     private List<String> getTestDrlFile() {  
  124.         List<String> drlFilePath = new ArrayList<String>();  
  125.         drlFilePath  
  126.                 .add("D:/workspace2/DroolsDemo/src/com/drools/demo/point/addpoint.drl");  
  127.         drlFilePath  
  128.                 .add("D:/workspace2/DroolsDemo/src/com/drools/demo/point/subpoint.drl");  
  129.   
  130.         return drlFilePath;  
  131.     }  
  132. }  

 

为了获取单实例的RuleBase,我们定义一个工厂类

 

  1. import org.drools.RuleBase;  
  2. import org.drools.RuleBaseFactory;  
  3.   
  4. /** 
  5.  * RuleBaseFacatory 单实例RuleBase生成工具 
  6.  * @author quzishen 
  7.  */  
  8. public class RuleBaseFacatory {  
  9.     private static RuleBase ruleBase;  
  10.       
  11.     public static RuleBase getRuleBase(){  
  12.         return null != ruleBase ? ruleBase : RuleBaseFactory.newRuleBase();  
  13.     }  
  14. }  

 

剩下的就是定义两个规则文件,分别用于积分发放和积分扣减

addpoint.drl

 

  1. package com.drools.demo.point  
  2.   
  3. import com.drools.demo.point.PointDomain;  
  4.   
  5. rule birthdayPoint  
  6.     // 过生日,则加10分,并且将当月交易比数翻倍后再计算积分  
  7.     salience 100  
  8.     lock-on-active true  
  9.     when  
  10.         $pointDomain : PointDomain(birthDay == true)  
  11.     then  
  12.          pointDomain.setPoint( pointDomain.setPoint(pointDomain.getPoint()+10);  
  13.          pointDomain.setBuyNums( pointDomain.setBuyNums(pointDomain.getBuyNums()*2);  
  14.          pointDomain.setBuyMoney( pointDomain.setBuyMoney(pointDomain.getBuyMoney()*2);  
  15.          pointDomain.setBillThisMonth( pointDomain.setBillThisMonth(pointDomain.getBillThisMonth()*2);  
  16.           
  17.          pointDomain.recordPointLog( pointDomain.recordPointLog(pointDomain.getUserName(),"birthdayPoint");  
  18. end  
  19.   
  20. rule billThisMonthPoint  
  21.     // 2011-01-08 - 2011-08-08每月信用卡还款3次以上,每满3笔赠送30分  
  22.     salience 99  
  23.     lock-on-active true  
  24.     date-effective "2011-01-08 23:59:59"  
  25.     date-expires "2011-08-08 23:59:59"  
  26.     when  
  27.         $pointDomain : PointDomain(billThisMonth >= 3)  
  28.     then  
  29.          pointDomain.setPoint( pointDomain.setPoint(pointDomain.getPoint()+$pointDomain.getBillThisMonth()/3*30);  
  30.          pointDomain.recordPointLog( pointDomain.recordPointLog(pointDomain.getUserName(),"billThisMonthPoint");  
  31. end  
  32.   
  33. rule buyMoneyPoint  
  34.     // 当月购物总金额100以上,每100元赠送10分  
  35.     salience 98  
  36.     lock-on-active true  
  37.     when  
  38.         $pointDomain : PointDomain(buyMoney >= 100)  
  39.     then  
  40.          pointDomain.setPoint( pointDomain.setPoint(pointDomain.getPoint()+ (int)$pointDomain.getBuyMoney()/100 * 10);  
  41.          pointDomain.recordPointLog( pointDomain.recordPointLog(pointDomain.getUserName(),"buyMoneyPoint");  
  42. end  
  43.   
  44. rule buyNumsPoint  
  45.     // 当月购物次数5次以上,每五次赠送50分  
  46.     salience 97  
  47.     lock-on-active true  
  48.     when  
  49.         $pointDomain : PointDomain(buyNums >= 5)  
  50.     then  
  51.          pointDomain.setPoint( pointDomain.setPoint(pointDomain.getPoint()+$pointDomain.getBuyNums()/5 * 50);  
  52.          pointDomain.recordPointLog( pointDomain.recordPointLog(pointDomain.getUserName(),"buyNumsPoint");  
  53. end  
  54.   
  55. rule allFitPoint  
  56.     // 特别的,如果全部满足了要求,则额外奖励100分  
  57.     salience 96  
  58.     lock-on-active true  
  59.     when  
  60.         $pointDomain:PointDomain(buyNums >= 5 && billThisMonth >= 3 && buyMoney >= 100)  
  61.     then  
  62.          pointDomain.setPoint( pointDomain.setPoint(pointDomain.getPoint()+ 100);  
  63.          pointDomain.recordPointLog( pointDomain.recordPointLog(pointDomain.getUserName(),"allFitPoint");  
  64. end  

 

subpoint.drl

 

  1. package com.drools.demo.point  
  2.   
  3. import com.drools.demo.point.PointDomain;  
  4.   
  5. rule subBackNumsPoint  
  6.     // 发生退货,扣减10分  
  7.     salience 10  
  8.     lock-on-active true  
  9.     when  
  10.         $pointDomain : PointDomain(backNums >= 1)  
  11.     then  
  12.          pointDomain.setPoint( pointDomain.setPoint(pointDomain.getPoint()-10);  
  13.          pointDomain.recordPointLog( pointDomain.recordPointLog(pointDomain.getUserName(),"subBackNumsPoint");  
  14. end  
  15.   
  16. rule subBackMondyPoint  
  17.     // 退货金额大于100,扣减100分  
  18.     salience 9  
  19.     lock-on-active true  
  20.     when  
  21.         $pointDomain : PointDomain(backMondy >= 100)  
  22.     then  
  23.          pointDomain.setPoint( pointDomain.setPoint(pointDomain.getPoint()-10);  
  24.          pointDomain.recordPointLog( pointDomain.recordPointLog(pointDomain.getUserName(),"subBackMondyPoint");  
  25. end  

 

 

测试方法:

 

  1. public static void main(String[] args) throws IOException {  
  2.         PointRuleEngine pointRuleEngine = new PointRuleEngineImpl();  
  3.         while(true){  
  4.             InputStream is = System.in;  
  5.             BufferedReader br = new BufferedReader(new InputStreamReader(is));  
  6.             String input = br.readLine();  
  7.               
  8.             if(null != input && "s".equals(input)){  
  9.                 System.out.println("初始化规则引擎...");  
  10.                 pointRuleEngine.initEngine();  
  11.                 System.out.println("初始化规则引擎结束.");  
  12.             }else if("e".equals(input)){  
  13.                 final PointDomain pointDomain = new PointDomain();  
  14.                 pointDomain.setUserName("hello kity");  
  15.                 pointDomain.setBackMondy(100d);  
  16.                 pointDomain.setBuyMoney(500d);  
  17.                 pointDomain.setBackNums(1);  
  18.                 pointDomain.setBuyNums(5);  
  19.                 pointDomain.setBillThisMonth(5);  
  20.                 pointDomain.setBirthDay(true);  
  21.                 pointDomain.setPoint(0l);  
  22.                   
  23.                 pointRuleEngine.executeRuleEngine(pointDomain);  
  24.                   
  25.                 System.out.println("执行完毕BillThisMonth:"+pointDomain.getBillThisMonth());  
  26.                 System.out.println("执行完毕BuyMoney:"+pointDomain.getBuyMoney());  
  27.                 System.out.println("执行完毕BuyNums:"+pointDomain.getBuyNums());  
  28.                   
  29.                 System.out.println("执行完毕规则引擎决定发送积分:"+pointDomain.getPoint());  
  30.             } else if("r".equals(input)){  
  31.                 System.out.println("刷新规则文件...");  
  32.                 pointRuleEngine.refreshEnginRule();  
  33.                 System.out.println("刷新规则文件结束.");  
  34.             }  
  35.         }  
  36.     }  

 

执行结果:

-----------------

增加对hello kity的类型为birthdayPoint的积分操作记录.
增加对hello kity的类型为billThisMonthPoint的积分操作记录.
增加对hello kity的类型为buyMoneyPoint的积分操作记录.
增加对hello kity的类型为buyNumsPoint的积分操作记录.
增加对hello kity的类型为allFitPoint的积分操作记录.
增加对hello kity的类型为subBackNumsPoint的积分操作记录.
增加对hello kity的类型为subBackMondyPoint的积分操作记录.
执行完毕BillThisMonth:10
执行完毕BuyMoney:1000.0
执行完毕BuyNums:10
执行完毕规则引擎决定发送积分:380

 

 

<dependency>
 <groupId>org.drools</groupId>
 <artifactId>drools-core</artifactId>
 <version>5.5.0.Final</version>
</dependency>
<dependency>
 <groupId>org.drools</groupId>
 <artifactId>drools-compiler</artifactId>
 <version>5.5.0.Final</version>
</dependency>
深入浅出 Drools 规则引擎 规则引擎是一种软件系统组件,设计目的是将业务决策逻辑从应用程序的主流程中解耦出来,使得业务规则可以独立于应用程序代码进行管理和变更。这种机制极大地提高了业务灵活性和可维护性,尤其是在那些业务规则频繁变动或者十分复杂的环境中。本文将介绍 Drools 的基本概念和简单引用,让你能快速上手使用 Drools 规则引擎。 阅读详情

相关推荐

Java规则引擎Drools急速入门

(1)什么是规则引擎全称为业务规则管理系统,英⽂名为BRMS(即 Business Rule Management System)。规则引擎的主要思想是将应用程序中的业务决策部分分离出来,并使用预定义的语义模块编写业务决策(业务规则),由用户或开发者在需要时进行配置、管理。需要注意的是规则引擎并不是一个具体的技术框架,而是指的⼀类系统,即业务规则管理系统。目前市面上具体的规则引擎产品有:drools、VisualRules、iLog等,使用最为广泛并且开源的是Drools。

llg3189609554的博客 1495

巨详细的规则引擎 Drools——小白也可食用

巨详细的规则引擎 Drools——小白也可食用

小李的便利店 2万+

Drools规则引擎 Java

前言: Drools是一款基于Java的开源规则引擎   实现了将业务决策从应用程序中分离出来。   优点:     1、简化系统架构,优化应用     2、提高系统的可维护性和维护成本     3、方便系统的整合     4、减少编写“硬代码”业务规则的成本和风险 不多说,直接low代码,此例是使用springboot项目为基础: 1.需添加maven依赖 使用7.x: ...

湖人•总冠军 7341

【Java】规则引擎 Drools

规则引擎,全称为业务规则管理系统,规则引擎的主要思想是将应用程序中的业务决策部分分离出来,并使用预定义的语义模块编写业务决策(业务规则),由用户或开发者在需要时进行配置、管理。需要注意的是规则引擎并不是一个具体的技术框架,而是指的一类系统。目前市面上具体的规则引擎产品有:drools、VisualRules、iLog等。规则引擎实现了将业务决策从应用程序代码中分离出来,接收数据输入,解释业务规则,并根据业务规则做出业务决策。规则引擎其实就是一个输入输出平台。

开心星人的博客 1429

探索Drools:Java世界的规则引擎

在现代软件开发中,处理复杂业务逻辑是一个常见的挑战。传统的编程方法可能会导致代码复杂、难以维护,而且对于频繁变化的业务需求缺乏灵活性。为了解决这些问题,开发人员转向规则引擎,其中 Drools 是一款备受推崇的 Java 规则引擎。本文将探讨 Drools 的特性、优势以及如何在项目中使用它。

微笑听雨 9077

JFET放大电路实例设计仿真

参照《晶体管电路设计》中的例子 JFET 2SK184 JFET 2SK184 数据手册如下 电路设计 共源放大 步骤:1、静态工作点 2N4416 1ma 2、RD和RS A=5 5:1 RS 2V /1m=2k RD 5k 3、偏压VG 根据传输特性 VGS-ID vgs=-0.7 vg=2-0.7=1.3 400k^2/50k...

f的博客 7443

Java中的基于规则的引擎(如Drools)

Drools是一个基于规则的引擎,使用一种声明性语言来定义复杂的业务规则。Drools提供了一种规则文件(.drl),用于编写业务规则,并且这些规则可以在运行时动态加载和执行。Drools作为一个开源的基于规则的引擎,提供了强大的规则管理和执行能力。通过使用Drools,可以将业务规则从应用逻辑中分离出来,使得系统更具灵活性和可维护性。在本文中,我们介绍了Drools的基本概念和优势,详细讲解了如何安装和配置Drools,并通过一个示例展示了如何在Java应用中集成Drools。

weixin_53840353的博客 1435

从solidworks导出URDF模型

一、下载sw_urdf_exporter插件 ROS目前提供了SolidWorks转URDF的插件,叫做sw_urdf_exporter,从http://wiki.ros.org/sw_urdf_exporter下载sw2urdfSetup.exe文件,下载后点击安装,安装完成后就能在solidworks中导出URDF模型了。 二、创建solidworks模型 下面以较为简单的四轮小车为例进行说...

weixin_45168199的博客 4万+

Java规则引擎-Drools

InfoQ发布了一个关于规则引擎的介绍Real-World Rule Engines,原文 http://www.infoq.com/articles/Rule-Engines ONJava上也有两篇文章:Give Your Business Logic a Framework with Drools http://www.onjava.com/lpt/a/6093Using Droo

纯月部落 2210

NVIDIA DRIVE SDK学习(二)——NvMedia

可以通过使用NvSciBuf API通过NvMedia Tensor属性分配NvSciBuf来创建NvMedia张量。由于NvSciBuf API有助于NvMedia和NVIDIA®CUDA®之间的数据共享,这使得分配的张量可以在NvSciBuf API允许的情况下重复使用。它支持图像聚合操作。NvSciSync组件使得NvMedia组件可以与其他组件保持同步,比如CUDA组件、基于NvSciSync的组件等。立体视差模式:在这种模式下,该模块通过左图像和右图像来产生立体视差,从而进行物体深度测量。

weixin_39592381的博客 3047

逆向Shopee签名机制:从参数分析到稳定采集方案

本文深入解析了Shopee签名机制的逆向过程,从参数分析到稳定采集方案的实现。通过抓包定位关键参数`sap-ri`和`x-sap-sec`,还原了签名生成算法,并提供了Python实现代码。文章还分享了反反爬策略、性能优化技巧及长期维护建议,帮助开发者构建稳定的Shopee数据采集方案。

weixin_27722377的博客 676

drools in java_JAVA规则引擎 -- Drools

Drools是一个基于java的规则引擎,开源的,可以将复杂多变的规则从硬编码中解放出来,以规则脚本的形式存放在文件中,使得规则的变更不需要修正代码重启机器就可以立即在线上环境生效。1、Drools语法开始语法之前首先要了解一下drools的基本工作过程,通常而言我们使用一个接口来做事情,首先要穿进去参数,其次要获取到接口的实现执行完毕后的结果,而drools也是一样的,我们需要传递进去数据,用于...

weixin_42636895的博客 530

el-transfer和el-tree进行结合搞一个树形穿梭框

由于业务需求需要在穿梭框里使用树形结构,但是本身element里并不支持,于是参考了别的大佬发的文章作为思路及后续自己新增了一些处理功能。

bbkhhvv的博客 6307

java营销活动动态引擎规则_JAVA规则引擎 Drools 教程

我们的日常生活是由规则驱动的。每次我们在开车的时候停在红灯处,之所以这样做,因为我们遵循一条规则,灯变红时我们应该停下来。如果你跳起来,最终会落到地面,这是由地球引力所决定的,它可以被表示成简单的数学方程。然而,对于我们生活日常中的规则,我们使用更加简单的结构来表示:当 XXX 的时候,做 XXX 的事。1 2when 满足什么样的条件 then 最终结果在程序中普遍的存在一些业务逻辑规则...

weixin_39847728的博客 1475

通达信强龙趋势幅图指标 - 精准捕捉趋势,把握强势行情,多角度分析个股,强弱一目了然

STICKLINE(趋势>0 AND SJTJ,4.8,5.8,1.5,0),COLORYELLOW;STICKLINE(资金>0 AND SJTJ,1.2,2.2,1.5,0),COLOR0080FF;STICKLINE(异动>0 AND SJTJ,0,1,1.5,0),COLORFF0080;STICKLINE(异动=0 AND SJTJ,0,1,1.5,1),COLORGRAY;

Q1809330692的博客 5643

【OpenFOAM】-olaFlow-算例10-wavemakerTank

采用 Flap和Piston两种方式的动网格进行造波

ou_no的博客 2169

java规则引擎Drools实战

规则引擎,全称为业务规则管理系统,英文名为BRMS(即Business Rule Management System)。规则引擎的主要思想是将应用程序中的业务决策部分分离出来,并使用预定义的语义模块编写业务决策(业务规则),由用户或开发者在需要时进行配置、管理。

fegus的博客 5645

19、利用PostGIS进行空间分析:更高效的矢量分析方法

本文介绍了如何利用PostGIS进行高效灵活的矢量空间分析,重点探讨了在选址安静住宅场景中使用缓冲区和距离测量两种方法的实现与优化。通过QGIS与PostGIS结合,演示了数据上传、CTE应用、ST_Intersects与ST_Distance函数对比,并深入分析了横向子查询在提升查询性能和代码可读性方面的优势。文章还比较了不同方法的适用场景,并以房地产开发选址为例展示了完整分析流程,最后总结了PostGIS在空间分析中的强大能力与未来应用前景。

d3e4f的博客 92

java规则引擎一:Drools

Drools是一个基于java的开源规则引擎, 规则引擎基本都只有一个逻辑就可以解释清楚: when…then… 当达到什么条件的时候,触发某一个动作。 Drools是java项目中常用的规则引擎之一。 规则引擎的应用场景单一,但是用处很大。 例如在某个场景下 有100个方法都要修改数据库的数据,且修改后都要有一个动作,就是想某一个系统发送一条消息。 传统的解决方案中,需要100个...

专注赚钱的程序员 1205

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

java drools demo_[Drools]JAVA规则引擎 -- Drools 2

packagecom.drools.demo.point;importJava.io.File;importjava.io.FileNotFoundException;importjava.io.FileReader;importjava.io.Reader;importjava.io.StringReader;importjava.util.ArrayList;importjav...

weixin_36046832的博客 214

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

java 规则引擎 drools框架

1.  drools是什么? drools是一个基于java语言的规则引擎框架。解决商业系统中复杂的业务逻辑硬编码到程序代码中带来不便的问题。drools的出现,可以把业务逻辑独立于程序代码,并且还能实时的更改业务逻辑。支持简单脚本语言的规则实现,也支持通用开发语言的嵌入开发 2.  规则引擎的数据流   1)接收输入数据;   2)解释业务规则;   3)做出业务决策 dro

courage的专栏 5183

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

Drools(JAVA规则引擎)开发指南

Drools JAVA规则引擎 Drools开发指南

CartoonMiao的博客 5404

JAVA开发Drools规则引擎使用

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档### 使用Drools生成规则的步骤。

qq_56996335的博客 363

Java开源规则引擎-Drools

Java开源规则引擎-Drools 1. Drools规则引擎介绍 1.1  Drools基本介绍 Drools是用Java语言编写的开放源码的规则引擎。 Drools使用RETE算法对规则进行求值,在Drools6.0(当前最新版本)中还引进了PHREAK算法,Drools 允许使用声明方式表达业务逻辑。可以使用非 XML 的本地语言编写规则,从而便于学习

龙腾四海365的专栏 1722
上一篇: 生成验证码
下一篇: 配置文件或模板中的占位符替换工具类.
杜引强
博客等级 码龄13年 806粉丝 68原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值