Drools 5 采用了原生的规则语言,那是一种非 XML 文本格式。在符号方面,这种格式是非常轻量的,它的应用非常简单。可以适用于比较复杂的业务逻辑,本例是用于计费系统的批价,粗略来说,有按次收费,按月收费,按照流量收费,又根据前提不同,使用不同的优惠策略,比如购买了某产品赠送800通话实践100分钟,又有可能根据当月实际使用天数赠送一定的通话时长。如此复杂场景使用规则引擎再好不过了,将动态的都用规则标识,模型里只存有静态数据。
首先Drools 规则要卸载drl 的文件里,通过程序加载这个drl,然后才可以运算
1. 引入jar包(maven 编译)
<dependency> <groupId>org.drools</groupId> <artifactId>drools-core</artifactId> <version>5.0.1</version> </dependency> <dependency> <groupId>org.drools</groupId> <artifactId>drools-compiler</artifactId> <version>5.0.1</version> </dependency>
2. 包装下drools
public class RuleRunner { public RuleRunner() { } private static final String RULES_FILE="rules/charge.drl"; public void runRules(Object[] facts){ KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase(); KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder(); System.out.println( "Loading file: " + RULES_FILE ); kbuilder.add( ResourceFactory.newClassPathResource( RULES_FILE,RuleRunner.class ),ResourceType.DRL ); if (kbuilder.hasErrors() ) { throw new ServiceException("charge.drl is a invalid rule file!"); } Collection<KnowledgePackage> pkgs = kbuilder.getKnowledgePackages(); kbase.addKnowledgePackages( pkgs ); StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession(); for ( int i = 0; i < facts.length; i++ ) { Object fact = facts[i]; System.out.println( "Inserting fact: " + fact ); ksession.insert( fact ); } ksession.fireAllRules(); } }
3. 调用这个封装进行异步的规则处理
Object[] facts={chargeRulesModel,chargePriceResult}; new RuleRunner().runRules(facts);
facts 就是要传入传出的对象。
4. 一个规则的解析
#created on: 2010-4-26 package charge #list any import classes here. import java.math.BigDecimal; rule "rule_800yz:be707 -2" #800月租费优惠 规则头注释 when #条件 $chargeModel : ChargeRulesModel($pricePlan:pricePlan,$featureList:featureList,eval($pricePlan.getPricePlanMain().getRuleCode().equals("rule_800yz")),eval(String.valueOf($featureList.get("pp900_1000")).equals("10Express"))) $chargeResult : ChargePriceResult() then # 执行逻辑 double price=$pricePlan.getCyclePolicy().getPrice(); int usage=(Integer)($featureList.get("pp900_61")); int accountLength=(Integer)($featureList.get("pp900_59")); int totalAccount=(Integer)($featureList.get("pp900_88")); int preferValue= Integer.parseInt($pricePlan.getPreferentialPolicy().getPreferentValue()); ##总使用量-赠送量>账期 则取账期的使用量作为使用天数 if(totalAccount- preferValue>= accountLength){ #使用类似java语言的判断逻辑 usage= accountLength; }else{ usage = totalAccount- preferValue; } BigDecimal result= new BigDecimal(price*usage/accountLength); $chargeResult.setAmount(result); System.out.println("800月租费优惠"); end
主要包含注释,条件,要执行的业务,还可以写方法-也就相当于helper类,实际运行时会转化为java类,但是不建议这么写,你完全可以另外写个java类,这里调用就可以了。
到这里就可以完成你的drools 应用了,具体原理下回分解