13.代碼中調(diào)用規(guī)則

2019-09-19 12:07 更新

13.代碼中調(diào)用規(guī)則

概述

在URule Pro當中,是不能直接調(diào)用具體的規(guī)則文件的,我們需要先將定義好的規(guī)則文件放到知識包中,然后才可以對規(guī)則文件進行測試和調(diào)用。

在代碼中調(diào)用知識包,需要先通過KnowledgeService接口可獲取指定的知識包ID對應的構(gòu)建好的資源包信息,然后通過知識包來創(chuàng)建具體的KnowledgeSession對象,接下來插入相關(guān)業(yè)務對象,最后執(zhí)行具體的規(guī)則調(diào)用。

KnowledgeService接口源碼如下:

package com.bstek.urule.runtime.service;
import java.io.IOException;
import com.bstek.urule.runtime.KnowledgePackage;
/**
 * @author Jacky.gao
 * @since 2015年1月28日
 */
public interface KnowledgeService {
    public static final String BEAN_ID="urule.knowledgeService";
    /**
     * 根據(jù)給定的資源包ID獲取對應的KnowledgePackage對象
     * @param packageId 項目名稱加資源包ID,格式為:projectName/packageId
     * @return 返回與給定的資源包ID獲取對應的KnowledgePackage對象
     * @throws IOException
     */
    KnowledgePackage getKnowledge(String packageId) throws IOException;
    /**
     * 根據(jù)給定的一個或多個資源包ID獲取對應的KnowledgePackage對象的集合
     * @param packageIds 資源包ID數(shù)組
     * @return 返回與給定的一個或多個資源包ID獲取對應的KnowledgePackage對象集合
     * @throws IOException
     */
    KnowledgePackage[] getKnowledges(String[] packageIds) throws IOException;
}

可以看到,這個接口中有兩個方法可供使用,一個是給一個知識包ID(格式為:projectName/packageId)返回一個對應的KnowledgePackage對象;另一個是給一個或多個知識包ID,返回一個集合類型的KnowledgePackage對象。在URule Pro當中,對于一個知識包,在使用時引擎會將其構(gòu)建成KnowledgePackage對象,在這個KnowledgePackage對象中包含了所有由向決策集、決策表、交叉決策表、決策樹、評分卡、復雜評分卡以及決策流等文件構(gòu)建的RuleSet對象,以及由規(guī)則流構(gòu)成的FlowDefinition對象。

在使用getKnowledge方法獲取某個指定的package時,要給一個資源包ID,需要注意的是資源包的ID在定義要要包含資源包所在項目名稱,格式為:projectName/packageId

通過KnowledgeService接口獲取到KnowledgePackage對象后,接下來就可通過KnowledgePackage對象創(chuàng)建com.bstek.urule.runtime.KnowledgeSession對象,這個對象就是引擎提供的與業(yè)務數(shù)據(jù)交互的接口,通過這個接口,可將需要的業(yè)務數(shù)據(jù)對象插入到引擎當中,最后根據(jù)需要執(zhí)行規(guī)則或規(guī)則流。

package com.bstek.urule.runtime;
import java.util.Map;
import com.bstek.urule.runtime.agenda.AgendaFilter;
/**
 * @author Jacky.gao
 * @since 2015年1月8日
 */
public interface KnowledgeSession extends WorkingMemory{
    /**
     * 執(zhí)行當前WorkMemory中所有滿足條件的規(guī)則
     * @return 返回一個ExecutionResponse對象,其中包含規(guī)則執(zhí)行耗時,滿足條件的規(guī)則,執(zhí)行的規(guī)則等信息
     */
    ExecutionResponse fireRules();
    /**
     * 對當前WorkMemory中所有滿足條件的規(guī)則進行過濾執(zhí)行
     * @param filter 對滿足條件的規(guī)則進行過濾
     * @return 返回一個ExecutionResponse對象,其中包含規(guī)則執(zhí)行耗時,滿足條件的規(guī)則,執(zhí)行的規(guī)則等信息
     */
    ExecutionResponse fireRules(AgendaFilter filter);
    /**
     * 對當前WorkMemory中所有滿足條件的規(guī)則進行過濾執(zhí)行,并向WorkingMemory中設置一個Map的參數(shù)對象
     * @param parameters 向WorkingMemory中設置一個Map的參數(shù)對象
     * @param filter 對滿足條件的規(guī)則進行過濾
     * @return 返回一個ExecutionResponse對象,其中包含規(guī)則執(zhí)行耗時,滿足條件的規(guī)則,執(zhí)行的規(guī)則等信息
     */
    ExecutionResponse fireRules(Map<String,Object> parameters,AgendaFilter filter);
    /**
     * 對當前WorkMemory中所有滿足條件的規(guī)則進行執(zhí)行,并定義執(zhí)行的最大數(shù)目,超出后就不再執(zhí)行
     * @param max 執(zhí)行規(guī)則的最大數(shù)目
     * @return 返回一個ExecutionResponse對象,其中包含規(guī)則執(zhí)行耗時,滿足條件的規(guī)則,執(zhí)行的規(guī)則等信息
     */
    ExecutionResponse fireRules(int max);
    /**
     * 對當前WorkMemory中所有滿足條件的規(guī)則進行執(zhí)行,并定義執(zhí)行的最大數(shù)目,超出后就不再執(zhí)行,<br>
     * 并向WorkingMemory中設置一個Map的參數(shù)對象
     * @param parameters 向WorkingMemory中設置一個Map的參數(shù)對象
     * @param max 執(zhí)行規(guī)則的最大數(shù)目
     * @return 返回一個ExecutionResponse對象,其中包含規(guī)則執(zhí)行耗時,滿足條件的規(guī)則,執(zhí)行的規(guī)則等信息
     */
    ExecutionResponse fireRules(Map<String,Object> parameters,int max);
    /**
     * 對當前WorkMemory中所有滿足條件的規(guī)則進行過濾執(zhí)行,并定義執(zhí)行數(shù)目的最大值
     * @param filter 對滿足條件的規(guī)則進行過濾
     * @param max 執(zhí)行規(guī)則的最大數(shù)目
     * @return 返回一個ExecutionResponse對象,其中包含規(guī)則執(zhí)行耗時,滿足條件的規(guī)則,執(zhí)行的規(guī)則等信息
     */
    ExecutionResponse fireRules(AgendaFilter filter,int max);
    /**
     * 對當前WorkMemory中所有滿足條件的規(guī)則進行過濾執(zhí)行,并定義執(zhí)行數(shù)目的最大值,<br>
     * 并向WorkingMemory中設置一個Map的參數(shù)對象
     * @param parameters 向WorkingMemory中設置一個Map的參數(shù)對象
     * @param filter 對滿足條件的規(guī)則進行過濾
     * @param max 執(zhí)行規(guī)則的最大數(shù)目
     * @return 返回一個ExecutionResponse對象,其中包含規(guī)則執(zhí)行耗時,滿足條件的規(guī)則,執(zhí)行的規(guī)則等信息
     */
    ExecutionResponse fireRules(Map<String,Object> parameters,AgendaFilter filter,int max);
    /**
     * 對當前WorkMemory中所有滿足條件的規(guī)則進行執(zhí)行,并向WorkingMemory中設置一個Map的參數(shù)對象
     * @param parameters 向WorkingMemory中設置一個Map的參數(shù)對象
     * @return 返回一個ExecutionResponse對象,其中包含規(guī)則執(zhí)行耗時,滿足條件的規(guī)則,執(zhí)行的規(guī)則等信息
     */
    ExecutionResponse fireRules(Map<String,Object> parameters);
    /**
     * 根據(jù)規(guī)則流ID,執(zhí)行目標規(guī)則流
     * @param processId 要執(zhí)行的規(guī)則流ID
     * @return 返回一個ExecutionResponse對象,其中包含規(guī)則流執(zhí)行耗時信息
     */
    ExecutionResponse startProcess(String processId);
    /**
     * 根據(jù)規(guī)則流ID,執(zhí)行目標規(guī)則流,并向WorkingMemory中設置一個Map的參數(shù)對象
     * @param processId 要執(zhí)行的規(guī)則流ID
     * @param parameters 向WorkingMemory中設置一個Map的參數(shù)對象
     * @return 返回一個ExecutionResponse對象,其中包含規(guī)則流執(zhí)行耗時信息
     */
    ExecutionResponse startProcess(String processId,Map<String,Object> parameters);
}

可以看到KnowledgeSession接口擴展自WorkingMemory接口,WorkingMemory接口源碼如下:

package com.bstek.urule.runtime;
import java.util.List;
import java.util.Map;


/**
 * @author Jacky.gao
 * @since 2015年1月8日
 */
public interface WorkingMemory {
    /**
     * 插入一個業(yè)務數(shù)據(jù)對象,對應到規(guī)則當中就是一個變量對象
     * @param fact 目標業(yè)務數(shù)據(jù)對象
     * @return 插入是否成功
     */
    boolean insert(Object fact);
    /**
     * 利用當前WorkingMemory中的規(guī)則信息來評估當前與業(yè)務對象,看其是否會滿足相關(guān)規(guī)則的條件,同時將該對象插入到WorkingMemory
     * @param fact 要評估的對象
     */
    void assertFact(Object fact);
    /**
     * 更新一個在當前WorkingMemory中已存在的業(yè)務對象,如果對象存在,那么WorkingMemory會重新評估這個對象
     * @param fact 要更新的對象
     * @return 更新是否成功,如果對象不在WorkingMemory中,則返回false
     */
    boolean update(Object fact);
    /**
     * 移除一個在WorkingMemory中的對象,如果對象存在,那么會嘗試對已滿足條件的規(guī)則進行重新評估,
     * 看看當前對象的移除是否會影響已滿足條件的規(guī)則,如果有影響,則同樣移除已滿足條件的規(guī)則
     * @param obj 要移除的對象
     * @return 是否移除成功,如果在WorkingMemory中存在,則返回true,否則返回false
     */
    boolean retract(Object obj);
    /**
     * 獲取當前WorkingMemory中的某個參數(shù)值
     * @param key 參數(shù)對應的key值
     * @return 返回具體的值
     */
    Object getParameter(String key);
    /**
     * @return 返回所有的參數(shù)對象
     */
    Map<String,Object> getParameters();
    /**
     * @return 返回當前WorkingMemory中所有的業(yè)務數(shù)據(jù)對象
     */
    List<Object> getAllFacts();
    /**
     * @return 返回所有WorkingMemory中所有歷史業(yè)務數(shù)據(jù)對象
     */
    List<Object> getHistoryFacts();
}

要通過KnowledgePackage對象或這個對象的數(shù)組創(chuàng)建一個KnowledgeSession對象,可以通過com.bstek.urule.runtime.KnowledgeSessionFactory類中下面兩個靜態(tài)方法實現(xiàn):

/**
 * 創(chuàng)建一個普通的KnowledgeSession對象
 * @param knowledgePackage 創(chuàng)建KnowledgeSession對象所需要的KnowledgePackage對象
 * @return 返回一個新的KnowledgeSession對象
 */
public static KnowledgeSession newKnowledgeSession(KnowledgePackage knowledgePackage){
    return new KnowledgeSessionImpl(knowledgePackage);
}


/**
 * 創(chuàng)建一個普通的KnowledgeSession對象
 * @param knowledgePackage 創(chuàng)建KnowledgeSession對象所需要的KnowledgePackage集合對象
 * @return 返回一個新的KnowledgeSession對象
 */
public static KnowledgeSession newKnowledgeSession(KnowledgePackage[] knowledgePackages){
    return new KnowledgeSessionImpl(knowledgePackages);
}

單次調(diào)用

由于這兩個方法都是靜態(tài)方法,所以可以直接調(diào)用,下面的代碼中演示了完整的調(diào)用過程:

package tt;
import rete.test.Dept;
import rete.test.Employee;
import com.bstek.urule.Utils;
import com.bstek.urule.runtime.KnowledgePackage;
import com.bstek.urule.runtime.KnowledgeSession;
import com.bstek.urule.runtime.KnowledgeSessionFactory;
import com.bstek.urule.runtime.service.KnowledgeService;
/**
 * @author Jacky.gao
 * @since 2015年3月5日
 */
public class Invoke {
    public void doTest() throws Exception{
        //從Spring中獲取KnowledgeService接口實例
        KnowledgeService service=(KnowledgeService)Utils.getApplicationContext().getBean(KnowledgeService.BEAN_ID);
        //通過KnowledgeService接口獲取指定的資源包"projectName/test123"
        KnowledgePackage knowledgePackage=service.getKnowledge("projectName/test123");
        //通過取到的KnowledgePackage對象創(chuàng)建KnowledgeSession對象
        KnowledgeSession session=KnowledgeSessionFactory.newKnowledgeSession(knowledgePackage);


        Employee employee=new Employee();
        Dept dept=new Dept();
        dept.setLevel(12);
        employee.setDept(dept);
        employee.setSalary(111000);
        //將業(yè)務數(shù)據(jù)對象Employee插入到KnowledgeSession中
        session.insert(employee);
        //執(zhí)行所有滿足條件的規(guī)則
        session.fireRules();
    }
}

在上面的示例當中,獲取到KnowledgeSession對象后,向其中插入一個名為Employee業(yè)務數(shù)據(jù)對象,這樣引擎在計算時,會直接采用Employee中相關(guān)數(shù)據(jù),如有條件滿足,同時有對Employee中相關(guān)數(shù)據(jù)賦值,那么會直接反映到當前插入的這個Employee對象當中。

在實際使用中,可能還會向KnowledgeSession中添加參數(shù)數(shù)據(jù)(以Map形式添加),對應URule中的參數(shù)庫文件中定義的信息,引擎計算完成后,我們要通KnowledgeSession中的getParameter來獲取具體的參數(shù)對象,而不 能通過原添加的Map中獲取,如下代碼:

package tt;
import java.util.HashMap;
import java.util.Map;
import rete.test.Dept;
import rete.test.Employee;
import com.bstek.urule.Utils;
import com.bstek.urule.runtime.KnowledgePackage;
import com.bstek.urule.runtime.KnowledgeSession;
import com.bstek.urule.runtime.KnowledgeSessionFactory;
import com.bstek.urule.runtime.service.KnowledgeService;
/**
 * @author Jacky.gao
 * @since 2015年3月5日
 */
public class Invoke {
    public void doTest() throws Exception{
        //從Spring中獲取KnowledgeService接口實例
        KnowledgeService service=(KnowledgeService)Utils.getApplicationContext().getBean(KnowledgeService.BEAN_ID);
        //通過KnowledgeService接口獲取指定的資源包"test123"
        KnowledgePackage knowledgePackage=service.getKnowledge("projectName/test123");
        //通過取到的KnowledgePackage對象創(chuàng)建KnowledgeSession對象
        KnowledgeSession session=KnowledgeSessionFactory.newKnowledgeSession(knowledgePackage);


        Employee employee=new Employee();
        Dept dept=new Dept();
        dept.setLevel(12);
        employee.setDept(dept);
        employee.setSalary(111000);
        //將業(yè)務數(shù)據(jù)對象Employee插入到KnowledgeSession中
        session.insert(employee);
        //執(zhí)行所有滿足條件的規(guī)則


        Map<String,Object> parameter=new HashMap<String,Object>();
        parameter.put("count", 10);
        parameter.put("result", true);
        //觸發(fā)規(guī)則時并設置參數(shù)
        session.fireRules(parameter);


        //獲取計算后的result值,要通過KnowledgeSession,而不能通過原來的parameter對象
        boolean result=(Boolean)session.getParameter("result");
        System.out.println(result);
    }
}

從上面的代碼中可以看到,在規(guī)則計算完成后,在獲取計算后的參數(shù)中的result值時,我們并沒有用提供參數(shù)的parameter,而是通過KnowledgeSession的getParameter來實現(xiàn),這是因為在向KnowledgeSession設置參數(shù)時,引擎會將參數(shù)中所有的值取出并放入到引擎中內(nèi)置的一個Map中,以避免影響原參數(shù)的值。所以計算完成后,我們要通過KnowledgeSession的getParameter來獲取計算后的參數(shù)值。

如果我們的資源包中包含有規(guī)則流,那么在插入好相關(guān)業(yè)務數(shù)據(jù)對象后,可以通過KnowledgeSession中提供的startProcess來實現(xiàn)規(guī)則流的調(diào)用,如下面的代碼所示:

package tt;
import java.util.HashMap;
import java.util.Map;
import rete.test.Dept;
import rete.test.Employee;
import com.bstek.urule.Utils;
import com.bstek.urule.runtime.KnowledgePackage;
import com.bstek.urule.runtime.KnowledgeSession;
import com.bstek.urule.runtime.KnowledgeSessionFactory;
import com.bstek.urule.runtime.service.KnowledgeService;
/**
 * @author Jacky.gao
 * @since 2015年3月5日
 */
public class Invoke {
    public void doTest() throws Exception{
        //從Spring中獲取KnowledgeService接口實例
        KnowledgeService service=(KnowledgeService)Utils.getApplicationContext().getBean(KnowledgeService.BEAN_ID);
        //通過KnowledgeService接口獲取指定的資源包"test123"
        KnowledgePackage knowledgePackage=service.getKnowledge("projectName/test123");
        //通過取到的KnowledgePackage對象創(chuàng)建KnowledgeSession對象
        KnowledgeSession session=KnowledgeSessionFactory.newKnowledgeSession(knowledgePackage);


        Employee employee=new Employee();
        Dept dept=new Dept();
        dept.setLevel(12);
        employee.setDept(dept);
        employee.setSalary(111000);
        //將業(yè)務數(shù)據(jù)對象Employee插入到KnowledgeSession中
        session.insert(employee);
        //執(zhí)行所有滿足條件的規(guī)則


        Map<String,Object> parameter=new HashMap<String,Object>();
        parameter.put("count", 10);
        parameter.put("result", true);


        //開始規(guī)則流并設置參數(shù)
        session.startProcess("flow-test",parameter);


        //獲取計算后的result值,要通過KnowledgeSession,而不能通過原來的parameter對象
        boolean result=(Boolean)session.getParameter("result");
        System.out.println(result);
    }
}

在URule Pro當中,規(guī)則流中是不存在人工任務的,也就是說規(guī)則流的執(zhí)行是一次性完成的,這點與包含人工任務的工作流引擎不同,比如UFLO,在UFLO中有人工任務,所以開啟流程實例后可能需要多次完成人工任務才能完成一個流程實例。

批處理支持

實際業(yè)務當中,我們除了會做單條規(guī)則計算外,還有可能需要運行規(guī)則引擎來處理一大批數(shù)據(jù),這些數(shù)據(jù)可能有幾萬條,幾十萬條,甚至更多。在這種情況下,如果我們還是采用普通的KnowledgeSession在一個線程里處理大批量數(shù)據(jù)的話,那么引擎還是只能在當前線程里運行,這樣就會需要很長的時間才能可能將這幾十萬條甚至更多的數(shù)據(jù)處理完成,在這個時候,為了充分利用服務器較強的CPU性能,我們可以使用BatchSession利用多線程并行處理這些數(shù)據(jù)。顧名思義BatchSession是用來做批處理任務的會話對象,它是 URule Pro當中提供的多線程并行處理大批量業(yè)務數(shù)據(jù)的規(guī)則會話對象。

要得到一個BatchSession對象,我們也需要提供一個或多個KnowledgePackage對象,獲取KnowledgePackage對象的方法與上面介紹的方法相同,有了KnowledgePackage對象后,就可以利用KnowledgeSessionFactory類創(chuàng)建一個BatchSession對象。

在com.bstek.urule.runtime.KnowledgeSessionFactory類中除上面提到的兩個構(gòu)建KnowledgeSession的靜態(tài)方法外,還提供了另外八個可用于構(gòu)建BatchSession的靜態(tài)方法,其源碼如下:

/**
     * 創(chuàng)建一個用于批處理的BatchSession對象,這里默認將開啟10個普通的線程池來運行提交的批處理任務,默認將每100個任務放在一個線程里處理
     * @param knowledgePackage 創(chuàng)建BatchSession對象所需要的KnowledgePackage對象
     * @return 返回一個新的BatchSession對象
     */
    public static BatchSession newBatchSession(KnowledgePackage knowledgePackage){
        return new BatchSessionImpl(knowledgePackage,BatchSession.DEFAULT_THREAD_SIZE,BatchSession.DEFAULT_BATCH_SIZE);
    }


    /**
     * 創(chuàng)建一個用于批處理的BatchSession對象,第二個參數(shù)來指定線程池中可用線程個數(shù),默認將每100個任務放在一個線程里處理
     * @param knowledgePackage 創(chuàng)建BatchSession對象所需要的KnowledgePackage對象
     * @param threadSize 線程池中可用的線程個數(shù)
     * @return 返回一個新的BatchSession對象
     */
    public static BatchSession newBatchSessionByThreadSize(KnowledgePackage knowledgePackage,int threadSize){
        return new BatchSessionImpl(knowledgePackage,threadSize,BatchSession.DEFAULT_BATCH_SIZE);
    }


    /**
     * 創(chuàng)建一個用于批處理的BatchSession對象,這里默認將開啟10個普通的線程池來運行提交的批處理任務,第二個參數(shù)用來決定單個線程處理的任務數(shù)
     * @param knowledgePackage 創(chuàng)建BatchSession對象所需要的KnowledgePackage對象
     * @param batchSize 單個線程處理的任務數(shù)
     * @return 返回一個新的BatchSession對象
     */
    public static BatchSession newBatchSessionByBatchSize(KnowledgePackage knowledgePackage,int batchSize){
        return new BatchSessionImpl(knowledgePackage,BatchSession.DEFAULT_THREAD_SIZE,batchSize);
    }


    /**
     * 創(chuàng)建一個用于批處理的BatchSession對象,第二個參數(shù)來指定線程池中可用線程個數(shù),第三個參數(shù)用來決定單個線程處理的任務數(shù)
     * @param knowledgePackage 創(chuàng)建BatchSession對象所需要的KnowledgePackage對象
     * @param threadSize 線程池中可用的線程個數(shù)
     * @param batchSize 單個線程處理的任務數(shù)
     * @return 返回一個新的BatchSession對象
     */
    public static BatchSession newBatchSession(KnowledgePackage knowledgePackage,int threadSize,int batchSize){
        return new BatchSessionImpl(knowledgePackage,threadSize,batchSize);
    }


    /**
     * 創(chuàng)建一個用于批處理的BatchSession對象,這里默認將開啟10個普通的線程池來運行提交的批處理任務,默認將每100個任務放在一個線程里處理
     * @param knowledgePackage 創(chuàng)建BatchSession對象所需要的KnowledgePackage集合對象
     * @return 返回一個新的BatchSession對象
     */
    public static BatchSession newBatchSession(KnowledgePackage[] knowledgePackages){
        return new BatchSessionImpl(knowledgePackages,BatchSession.DEFAULT_THREAD_SIZE,BatchSession.DEFAULT_BATCH_SIZE);
    }


    /**
     * 創(chuàng)建一個用于批處理的BatchSession對象,第二個參數(shù)來指定線程池中可用線程個數(shù),默認將每100個任務放在一個線程里處理
     * @param knowledgePackages 創(chuàng)建BatchSession對象所需要的KnowledgePackage集合對象
     * @param threadSize 線程池中可用的線程個數(shù)
     * @return 返回一個新的BatchSession對象
     */
    public static BatchSession newBatchSessionByThreadSize(KnowledgePackage[] knowledgePackages,int threadSize){
        return new BatchSessionImpl(knowledgePackages,threadSize,BatchSession.DEFAULT_BATCH_SIZE);
    }


    /**
     * 創(chuàng)建一個用于批處理的BatchSession對象,這里默認將開啟10個普通的線程池來運行提交的批處理任務,第二個參數(shù)用來決定單個線程處理的任務數(shù)
     * @param knowledgePackages 創(chuàng)建BatchSession對象所需要的KnowledgePackage集合對象
     * @param batchSize 單個線程處理的任務數(shù)
     * @return 返回一個新的BatchSession對象
     */
    public static BatchSession newBatchSessionByBatchSize(KnowledgePackage[] knowledgePackages,int batchSize){
        return new BatchSessionImpl(knowledgePackages,BatchSession.DEFAULT_THREAD_SIZE,batchSize);
    }


    /**
     * 創(chuàng)建一個用于批處理的BatchSession對象,第二個參數(shù)來指定線程池中可用線程個數(shù),第三個參數(shù)用來決定單個線程處理的任務數(shù)
     * @param knowledgePackages 創(chuàng)建BatchSession對象所需要的KnowledgePackage集合對象
     * @param threadSize 線程池中可用的線程個數(shù)
     * @param batchSize 單個線程處理的任務數(shù)
     * @return 返回一個新的BatchSession對象
     */
    public static BatchSession newBatchSession(KnowledgePackage[] knowledgePackages,int threadSize,int batchSize){
        return new BatchSessionImpl(knowledgePackages,threadSize,batchSize);
    }

前面介紹規(guī)則流中的決策節(jié)點時,了解到?jīng)Q策節(jié)點中支持百分比分流,這種百分比分流就要求必須是在使用BatchSession處理一批數(shù)據(jù)的時候,或者是一個用一個普通的KnowledgeSession一次性處理多條數(shù)據(jù)才有效,否則規(guī)則流只會走比例最高的那個分支。

BatchSession接口比較簡單,它只定義了兩個方法:

/**
     * 添加一個具體要執(zhí)行Business對象
     * @param business Business對象實例
     */
    void addBusiness(Business business);




    /**
     * 等待線程池中所有業(yè)務線程執(zhí)行完成,在進行批處理操作時一定要以此方法作為方法調(diào)用結(jié)尾
     */
    void waitForCompletion();

可以看到,它可以接收若干個名為com.bstek.urule.runtime.Business接口實例,Business接口比較簡單,它只有一個方法:

package com.bstek.urule.runtime;
/**
 * @author Jacky.gao
 * @since 2015年9月29日
 */
public interface Business {
    void execute(KnowledgeSession session);
}

在Business實現(xiàn)類中,我們的業(yè)務寫在execute方法當中,在這個方法中,只有一個KnowledgeSession對象,這個session對象就是我們與規(guī)則引擎操作的對象,示例代碼如下:

//從Spring中獲取KnowledgeService接口實例
KnowledgeService service=(KnowledgeService)Utils.getApplicationContext().getBean(KnowledgeService.BEAN_ID);
//通過KnowledgeService接口獲取指定的資源包"aaa"
KnowledgePackage knowledgePackage=service.getKnowledge("projectName/aaa");


//通過取的KnowledgePackage對象創(chuàng)建BatchSession對象,在這個對象中,我們將開啟5個線程,每個線程最多放置10個Bussiness接口實例運行
BatchSession batchSession=KnowledgeSessionFactory.newBatchSession(knowledgePackage, 5, 10);


for(int i=0;i<100;i++){
    batchSession.addBusiness(new Business(){
        @Override
        public void execute(KnowledgeSession session) {
            Employee employee=new Employee();
            employee.setSalary(11080);
            //將業(yè)務數(shù)據(jù)對象Employee插入到KnowledgeSession中
            session.insert(employee);
            session.startProcess("demo");
        }
    });
}
//等待所有的線程執(zhí)行完成,對于BatchSession調(diào)用來說,此行代碼必不可少,否則將導致錯誤
batchSession.waitForCompletion();
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號