您的位置:首页 > 编程语言 > Java开发

Java规则引擎学习-drools(五)

2013-01-11 12:05 621 查看
[align=right]字号:大 中 小[/align]

按照学习drools的系列文章的习惯,一般是理论+实践(示例),在Java规则引擎学习-drools(五),转了一篇基于Spring的规则引擎的集成的文章,本文将讨论怎么使用Spring集成drools。这里我想使用Springside中的对drools的集成做一个介绍:

1. BaseLoader.java

此类是是一个接口,其实现类将从数据库或drl文件中读取RuleBase,代码如下:

public interface BaseLoader {

public RuleBase buildRuleBase(String RulesetName, Date date) throws Exception;

}

2. FileRuleBaseLoader.java

此类是BaseLoader的实现类,负责从drl文件中读取并组装成Drools RuleBase。

代码如下:

public class FileRuleBaseLoader implements BaseLoader {

private Map ruleSetFileMap;

public void setRuleSetFileMap(Map ruleSetFileMap) {

this.ruleSetFileMap = ruleSetFileMap;

}

public RuleBase buildRuleBase(String ruleSetName, Date date) throws Exception {

String filePath = (String) ruleSetFileMap.get(ruleSetName);

if (filePath == null)

throw new Exception("No RuleSet found by Name:" + ruleSetName);

InputStream is = this.getClass().getResourceAsStream(filePath);

if (is == null)

throw new Exception("No RuleSet found by Name:" + ruleSetName);

return RuleBaseLoader.loadFromInputStream(is);

}

}

3. RuleService.java

public interface RuleService {

/**

* 执行规则

*

* @param ruleSetName 执行的规则集名

* @param facts 参与规则运算的事实列表

* @param date 运算日期,用于选择有效期内的规则

*/

public List executeRules(String ruleSetName, List facts, Date date) throws Exception;

/**

* 参见 excueteRules(String ruleSetName, List facts, Date date)

*/

public List executeRules(String ruleSetName, Object fact, Date date) throws Exception;

}

4. DroolsTemplate.java

public class DroolsTemplate implements RuleService {

private BaseLoader ruleBaseLoader;

private Cache ruleCache;

/**

* 执行规则,见接口定义

*/

public List executeRules(String ruleSetName, Object fact, Date date) throws Exception {

List facts = new ArrayList();

facts.add(fact);

return executeRules(ruleSetName, facts, date);

}

/**

* 执行规则,见接口定义

*/

public List executeRules(String ruleSetName, List facts, Date date) throws Exception {

RuleBase rb = loadRuleBase(ruleSetName, date);

WorkingMemory session = rb.newWorkingMemory();

for (Iterator objectIter = facts.iterator(); objectIter.hasNext();) {

session.assertObject(objectIter.next());

}

session.fireAllRules();

return session.getObjects();

}

/**

* 会先尝试从Cache中获取,如果为空则从数据库或drl文件中获取规则并重新编译RuleSet

*/

private RuleBase loadRuleBase(String ruleSetName, Date date) throws Exception {

RuleBase ruleBase = (RuleBase) EhCacheUtil.getCache(ruleCache, ruleSetName + date);

if (ruleBase == null) {

ruleBase = ruleBaseLoader.buildRuleBase(ruleSetName, date);

EhCacheUtil.setCache(ruleCache, ruleSetName + date, ruleBase);

}

return ruleBase;

}

public void setRuleBaseLoader(BaseLoader ruleBaseLoader) {

this.ruleBaseLoader = ruleBaseLoader;

}

public void setRuleCache(Cache ruleCache) {

this.ruleCache = ruleCache;

}

}

5. ApplicationContext-rule.xml

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN""http://www.springframework.org/dtd/spring-beans.dtd">

<beans default-autowire="byName">

<!-- Drools Template -->

<bean id="ruleService" class="org.springside.rule.DroolsTemplate">

<property name="ruleBaseLoader" ref="fileRuleBaseLoader"/>

</bean>

<bean id="fileRuleBaseLoader" class="org.springside.rule.FileRuleBaseLoader">

<property name="ruleSetFileMap">

<map>

<entry key="OrderPricing" value="drl/OrderPricing.xml"/>

</map>

</property>

</bean>

<bean id="ruleCache" class="org.springframework.cache.ehcache.EhCacheFactoryBean">

<property name="cacheName" value="ruleCache"/>

</bean>

</beans>

6. OrderPricing.xml

<?xml version="1.0"?>

<rule-set name="OrderPricing"

xmlns="http://drools.org/rules"

xmlns:groovy="http://drools.org/semantics/groovy"

xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"

xs:schemaLocation="http://drools.org/rules rules.xsd
http://drools.org/semantics/groovy groovy.xsd">

<rule name="discount">

<parameter identifier="order">

<class>org.springside.bookstore.domain.Order</class>

</parameter>

<groovy:condition>order.getTotalPrice() >=100</groovy:condition>

<groovy:consequence>

Double price = order.getTotalPrice() *0.9d;

order.setDiscountPrice(price);

order.addApplyRule(drools.getRuleName());

</groovy:consequence>

</rule>

</rule-set>

7. 需要说明的是:上述代码采用了Ehcache来缓存rulebase。具体细节见上面代码。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: