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

字号:大 中 小

按照学习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。具体细节见上面代码。

posted @ 2013-01-11 12:05  attitudedecidesall  Views(1165)  Comments(0Edit  收藏  举报