转载自:http://blog.csdn.net/sadfishsc/article/details/23456713
关于Drools 6.0的博文,写了很长时间。一方面是最近比较散漫,虽然也学了不点击打开链接少新的东西,但是不太愿意记录下来;另一方面是Drools本身比较繁琐,即便是入门也需要涉及很多内部的东西,越写越觉得动力不足。本文已经是第三次从头开始写的了。
首先介绍一下Drools。Drools是一个基于Java实现的规则引擎开源库,由JBoss基金会管理,最新的是6.0.1版本。6.0版本中,Drools推出了一套新的基于KIE概念的API,其目的是将之前版本中对规则引擎繁琐的调用和加载过程加以简化,效果拔群。
目前网上关于Drools 6.0的资料相对较少。以下是本人搜索到的两个较好的教程,以供学习:
http://blog.xiongzhijun.com/?cat=48(中文,Drools入门教程,涉及了很多Drools的基础概念、结构与语法)
http://docs.jboss.org/drools/release/6.0.1.Final/drools-docs/html_single/index.html(英文,6.0.1官方指南,涉及Drools的方方面面,适合进阶学习)
http://blog.csdn.net/quzishen/article/details/6163012(中文,5.x版本,可用于对照,且其中对DRL规则文件的讲解可供学习)
以下是本人编写的一个基于Drools 6.0实现的时钟的实例。
Java代码:
src/main/java/com.ibm.clock.Clock.java
- package com.ibm.clock;
- public class Clock {
- private int hour;
- private int minute;
- private int second;
- public int getHour() {
- return hour;
- }
- public void setHour(int hour) {
- this.hour = hour;
- }
- public int getMinute() {
- return minute;
- }
- public void setMinute(int minute) {
- this.minute = minute;
- }
- public int getSecond() {
- return second;
- }
- public void setSecond(int second) {
- this.second = second;
- }
- @Override
- public String toString() {
- return hour + ":" + minute + ":" + second;
- }
- }
src/main/java/com.ibm.clock.ClockTest.java
- package com.ibm.clock;
- import org.kie.api.KieServices;
- import org.kie.api.runtime.KieContainer;
- import org.kie.api.runtime.KieSession;
- public class ClockTest {
- public static void main(String[] args) {
- KieServices ks = KieServices.Factory.get();
- KieContainer kContainer = ks.getKieClasspathContainer();
- KieSession kSession = kContainer.newKieSession("session-clock");
- kSession.insert(new Clock());
- kSession.fireAllRules();
- kSession.dispose();
- }
- }
DRL规则文件:
src/main/resources/clock/clock.drl
- package com.ibm.clock
- rule "run"
- salience 1
- when
- c: Clock(!(hour == 1 && second == 1))
- then
- System.out.println(c);
- Thread.sleep(1000);
- c.setSecond(c.getSecond() + 1);
- update(c);
- end
- rule "second"
- salience 2
- when
- c: Clock(second == 60);
- then
- c.setMinute(c.getMinute() + 1);
- c.setSecond(0);
- update(c);
- end
- rule "minute"
- salience 3
- when
- c: Clock(minute == 60)
- then
- c.setHour(c.getHour() + 1);
- c.setMinute(0);
- update(c);
- end
Drools配置文件:
src/main/resources/META-INF/kmodule.xml
- <?xml version="1.0" encoding="UTF-8"?>
- <kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule">
- <kbase name="clock" packages="clock">
- <ksession name="session-clock" />
- </kbase>
- </kmodule>
需要说明的是:
1. 上述代码中有关Drools的功能类以及kmodule.xml配置文件中的标签的说明都可以在上面的两个链接的教程中找到;
2. Drools项目本身是一个maven项目,所以src/main/resources/META-INF/maven/pom.properties文件必须要有,而且已经设置groupId、artifactId、version的值,否则会出现NullPointerException异常;如果通过Eclipse创建Drools项目,maven的相关属性在创新过程中会要求填写,否则无法创建项目;
3. DRL规则文件在when之前可以设置的属性如下所示:
no-loop:在DRL的then子句中,如果出现insert、update、modify、retract等方法对实例(Fact)做出修改时,当前规则执行完成后会触发该规则使其再执行一次;将no-loop设置为true则会强制规则在出现上述方法的情况下也只执行一次
boolean型,默认值为false
ruleflow-group:基于ruleflow将规则分组
string型,无默认值
lock-on-active:规则可能会被其它规则调用而反复执行;将lock-on-active置为true可以强制使规则在任何条件下都只会执行一次,可视为no-loop的加强版
boolean型,默认值为false
salience:设置当前这条规则的执行优先级,数字越小优先级越高
int型,默认值为0
agenda-group:基于Agenda将规则分组;只有当某个Agenda组获取到焦点(focus)时,该组的规则才会被执行
string型,默认值为MAIN
auto-focus:与agenda-group配合使用,设置焦点的是否可以自动获取
boolean型,默认值为false
activation-group:不基于任何条件将规则分组
string型,无默认值
dialect:设置规则所使用的语言
string型,默认值根据package值判断,值域为java或mvel
data-effective:当前规则的生效时间
string型,无默认值;值中需包含日期和时间
data-expires:当前规则的失效时间
string型,无默认值;值中需包含日期和时间
duration:设置DRL文件开始执行之后延迟多长时间开始执行这条规则
long型,无默认值