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對應(yīng)的構(gòu)建好的資源包信息,然后通過知識包來創(chuàng)建具體的KnowledgeSession對象,接下來插入相關(guān)業(yè)務(wù)對象,最后執(zhí)行具體的規(guī)則調(diào)用。

KnowledgeService接口源碼如下:

  1. package com.bstek.urule.runtime.service;
  2. import java.io.IOException;
  3. import com.bstek.urule.runtime.KnowledgePackage;
  4. /**
  5. * @author Jacky.gao
  6. * @since 2015128
  7. */
  8. public interface KnowledgeService {
  9. public static final String BEAN_ID="urule.knowledgeService";
  10. /**
  11. * 根據(jù)給定的資源包ID獲取對應(yīng)的KnowledgePackage對象
  12. * @param packageId 項目名稱加資源包ID,格式為:projectName/packageId
  13. * @return 返回與給定的資源包ID獲取對應(yīng)的KnowledgePackage對象
  14. * @throws IOException
  15. */
  16. KnowledgePackage getKnowledge(String packageId) throws IOException;
  17. /**
  18. * 根據(jù)給定的一個或多個資源包ID獲取對應(yīng)的KnowledgePackage對象的集合
  19. * @param packageIds 資源包ID數(shù)組
  20. * @return 返回與給定的一個或多個資源包ID獲取對應(yīng)的KnowledgePackage對象集合
  21. * @throws IOException
  22. */
  23. KnowledgePackage[] getKnowledges(String[] packageIds) throws IOException;
  24. }

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

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

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

  1. package com.bstek.urule.runtime;
  2. import java.util.Map;
  3. import com.bstek.urule.runtime.agenda.AgendaFilter;
  4. /**
  5. * @author Jacky.gao
  6. * @since 201518
  7. */
  8. public interface KnowledgeSession extends WorkingMemory{
  9. /**
  10. * 執(zhí)行當前WorkMemory中所有滿足條件的規(guī)則
  11. * @return 返回一個ExecutionResponse對象,其中包含規(guī)則執(zhí)行耗時,滿足條件的規(guī)則,執(zhí)行的規(guī)則等信息
  12. */
  13. ExecutionResponse fireRules();
  14. /**
  15. * 對當前WorkMemory中所有滿足條件的規(guī)則進行過濾執(zhí)行
  16. * @param filter 對滿足條件的規(guī)則進行過濾
  17. * @return 返回一個ExecutionResponse對象,其中包含規(guī)則執(zhí)行耗時,滿足條件的規(guī)則,執(zhí)行的規(guī)則等信息
  18. */
  19. ExecutionResponse fireRules(AgendaFilter filter);
  20. /**
  21. * 對當前WorkMemory中所有滿足條件的規(guī)則進行過濾執(zhí)行,并向WorkingMemory中設(shè)置一個Map的參數(shù)對象
  22. * @param parameters 向WorkingMemory中設(shè)置一個Map的參數(shù)對象
  23. * @param filter 對滿足條件的規(guī)則進行過濾
  24. * @return 返回一個ExecutionResponse對象,其中包含規(guī)則執(zhí)行耗時,滿足條件的規(guī)則,執(zhí)行的規(guī)則等信息
  25. */
  26. ExecutionResponse fireRules(Map<String,Object> parameters,AgendaFilter filter);
  27. /**
  28. * 對當前WorkMemory中所有滿足條件的規(guī)則進行執(zhí)行,并定義執(zhí)行的最大數(shù)目,超出后就不再執(zhí)行
  29. * @param max 執(zhí)行規(guī)則的最大數(shù)目
  30. * @return 返回一個ExecutionResponse對象,其中包含規(guī)則執(zhí)行耗時,滿足條件的規(guī)則,執(zhí)行的規(guī)則等信息
  31. */
  32. ExecutionResponse fireRules(int max);
  33. /**
  34. * 對當前WorkMemory中所有滿足條件的規(guī)則進行執(zhí)行,并定義執(zhí)行的最大數(shù)目,超出后就不再執(zhí)行,<br>
  35. * 并向WorkingMemory中設(shè)置一個Map的參數(shù)對象
  36. * @param parameters 向WorkingMemory中設(shè)置一個Map的參數(shù)對象
  37. * @param max 執(zhí)行規(guī)則的最大數(shù)目
  38. * @return 返回一個ExecutionResponse對象,其中包含規(guī)則執(zhí)行耗時,滿足條件的規(guī)則,執(zhí)行的規(guī)則等信息
  39. */
  40. ExecutionResponse fireRules(Map<String,Object> parameters,int max);
  41. /**
  42. * 對當前WorkMemory中所有滿足條件的規(guī)則進行過濾執(zhí)行,并定義執(zhí)行數(shù)目的最大值
  43. * @param filter 對滿足條件的規(guī)則進行過濾
  44. * @param max 執(zhí)行規(guī)則的最大數(shù)目
  45. * @return 返回一個ExecutionResponse對象,其中包含規(guī)則執(zhí)行耗時,滿足條件的規(guī)則,執(zhí)行的規(guī)則等信息
  46. */
  47. ExecutionResponse fireRules(AgendaFilter filter,int max);
  48. /**
  49. * 對當前WorkMemory中所有滿足條件的規(guī)則進行過濾執(zhí)行,并定義執(zhí)行數(shù)目的最大值,<br>
  50. * 并向WorkingMemory中設(shè)置一個Map的參數(shù)對象
  51. * @param parameters 向WorkingMemory中設(shè)置一個Map的參數(shù)對象
  52. * @param filter 對滿足條件的規(guī)則進行過濾
  53. * @param max 執(zhí)行規(guī)則的最大數(shù)目
  54. * @return 返回一個ExecutionResponse對象,其中包含規(guī)則執(zhí)行耗時,滿足條件的規(guī)則,執(zhí)行的規(guī)則等信息
  55. */
  56. ExecutionResponse fireRules(Map<String,Object> parameters,AgendaFilter filter,int max);
  57. /**
  58. * 對當前WorkMemory中所有滿足條件的規(guī)則進行執(zhí)行,并向WorkingMemory中設(shè)置一個Map的參數(shù)對象
  59. * @param parameters 向WorkingMemory中設(shè)置一個Map的參數(shù)對象
  60. * @return 返回一個ExecutionResponse對象,其中包含規(guī)則執(zhí)行耗時,滿足條件的規(guī)則,執(zhí)行的規(guī)則等信息
  61. */
  62. ExecutionResponse fireRules(Map<String,Object> parameters);
  63. /**
  64. * 根據(jù)規(guī)則流ID,執(zhí)行目標規(guī)則流
  65. * @param processId 要執(zhí)行的規(guī)則流ID
  66. * @return 返回一個ExecutionResponse對象,其中包含規(guī)則流執(zhí)行耗時信息
  67. */
  68. ExecutionResponse startProcess(String processId);
  69. /**
  70. * 根據(jù)規(guī)則流ID,執(zhí)行目標規(guī)則流,并向WorkingMemory中設(shè)置一個Map的參數(shù)對象
  71. * @param processId 要執(zhí)行的規(guī)則流ID
  72. * @param parameters 向WorkingMemory中設(shè)置一個Map的參數(shù)對象
  73. * @return 返回一個ExecutionResponse對象,其中包含規(guī)則流執(zhí)行耗時信息
  74. */
  75. ExecutionResponse startProcess(String processId,Map<String,Object> parameters);
  76. }

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

  1. package com.bstek.urule.runtime;
  2. import java.util.List;
  3. import java.util.Map;
  4. /**
  5. * @author Jacky.gao
  6. * @since 201518
  7. */
  8. public interface WorkingMemory {
  9. /**
  10. * 插入一個業(yè)務(wù)數(shù)據(jù)對象,對應(yīng)到規(guī)則當中就是一個變量對象
  11. * @param fact 目標業(yè)務(wù)數(shù)據(jù)對象
  12. * @return 插入是否成功
  13. */
  14. boolean insert(Object fact);
  15. /**
  16. * 利用當前WorkingMemory中的規(guī)則信息來評估當前與業(yè)務(wù)對象,看其是否會滿足相關(guān)規(guī)則的條件,同時將該對象插入到WorkingMemory
  17. * @param fact 要評估的對象
  18. */
  19. void assertFact(Object fact);
  20. /**
  21. * 更新一個在當前WorkingMemory中已存在的業(yè)務(wù)對象,如果對象存在,那么WorkingMemory會重新評估這個對象
  22. * @param fact 要更新的對象
  23. * @return 更新是否成功,如果對象不在WorkingMemory中,則返回false
  24. */
  25. boolean update(Object fact);
  26. /**
  27. * 移除一個在WorkingMemory中的對象,如果對象存在,那么會嘗試對已滿足條件的規(guī)則進行重新評估,
  28. * 看看當前對象的移除是否會影響已滿足條件的規(guī)則,如果有影響,則同樣移除已滿足條件的規(guī)則
  29. * @param obj 要移除的對象
  30. * @return 是否移除成功,如果在WorkingMemory中存在,則返回true,否則返回false
  31. */
  32. boolean retract(Object obj);
  33. /**
  34. * 獲取當前WorkingMemory中的某個參數(shù)值
  35. * @param key 參數(shù)對應(yīng)的key值
  36. * @return 返回具體的值
  37. */
  38. Object getParameter(String key);
  39. /**
  40. * @return 返回所有的參數(shù)對象
  41. */
  42. Map<String,Object> getParameters();
  43. /**
  44. * @return 返回當前WorkingMemory中所有的業(yè)務(wù)數(shù)據(jù)對象
  45. */
  46. List<Object> getAllFacts();
  47. /**
  48. * @return 返回所有WorkingMemory中所有歷史業(yè)務(wù)數(shù)據(jù)對象
  49. */
  50. List<Object> getHistoryFacts();
  51. }

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

  1. /**
  2. * 創(chuàng)建一個普通的KnowledgeSession對象
  3. * @param knowledgePackage 創(chuàng)建KnowledgeSession對象所需要的KnowledgePackage對象
  4. * @return 返回一個新的KnowledgeSession對象
  5. */
  6. public static KnowledgeSession newKnowledgeSession(KnowledgePackage knowledgePackage){
  7. return new KnowledgeSessionImpl(knowledgePackage);
  8. }
  9. /**
  10. * 創(chuàng)建一個普通的KnowledgeSession對象
  11. * @param knowledgePackage 創(chuàng)建KnowledgeSession對象所需要的KnowledgePackage集合對象
  12. * @return 返回一個新的KnowledgeSession對象
  13. */
  14. public static KnowledgeSession newKnowledgeSession(KnowledgePackage[] knowledgePackages){
  15. return new KnowledgeSessionImpl(knowledgePackages);
  16. }

單次調(diào)用

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

  1. package tt;
  2. import rete.test.Dept;
  3. import rete.test.Employee;
  4. import com.bstek.urule.Utils;
  5. import com.bstek.urule.runtime.KnowledgePackage;
  6. import com.bstek.urule.runtime.KnowledgeSession;
  7. import com.bstek.urule.runtime.KnowledgeSessionFactory;
  8. import com.bstek.urule.runtime.service.KnowledgeService;
  9. /**
  10. * @author Jacky.gao
  11. * @since 201535
  12. */
  13. public class Invoke {
  14. public void doTest() throws Exception{
  15. //從Spring中獲取KnowledgeService接口實例
  16. KnowledgeService service=(KnowledgeService)Utils.getApplicationContext().getBean(KnowledgeService.BEAN_ID);
  17. //通過KnowledgeService接口獲取指定的資源包"projectName/test123"
  18. KnowledgePackage knowledgePackage=service.getKnowledge("projectName/test123");
  19. //通過取到的KnowledgePackage對象創(chuàng)建KnowledgeSession對象
  20. KnowledgeSession session=KnowledgeSessionFactory.newKnowledgeSession(knowledgePackage);
  21. Employee employee=new Employee();
  22. Dept dept=new Dept();
  23. dept.setLevel(12);
  24. employee.setDept(dept);
  25. employee.setSalary(111000);
  26. //將業(yè)務(wù)數(shù)據(jù)對象Employee插入到KnowledgeSession中
  27. session.insert(employee);
  28. //執(zhí)行所有滿足條件的規(guī)則
  29. session.fireRules();
  30. }
  31. }

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

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

  1. package tt;
  2. import java.util.HashMap;
  3. import java.util.Map;
  4. import rete.test.Dept;
  5. import rete.test.Employee;
  6. import com.bstek.urule.Utils;
  7. import com.bstek.urule.runtime.KnowledgePackage;
  8. import com.bstek.urule.runtime.KnowledgeSession;
  9. import com.bstek.urule.runtime.KnowledgeSessionFactory;
  10. import com.bstek.urule.runtime.service.KnowledgeService;
  11. /**
  12. * @author Jacky.gao
  13. * @since 201535
  14. */
  15. public class Invoke {
  16. public void doTest() throws Exception{
  17. //從Spring中獲取KnowledgeService接口實例
  18. KnowledgeService service=(KnowledgeService)Utils.getApplicationContext().getBean(KnowledgeService.BEAN_ID);
  19. //通過KnowledgeService接口獲取指定的資源包"test123"
  20. KnowledgePackage knowledgePackage=service.getKnowledge("projectName/test123");
  21. //通過取到的KnowledgePackage對象創(chuàng)建KnowledgeSession對象
  22. KnowledgeSession session=KnowledgeSessionFactory.newKnowledgeSession(knowledgePackage);
  23. Employee employee=new Employee();
  24. Dept dept=new Dept();
  25. dept.setLevel(12);
  26. employee.setDept(dept);
  27. employee.setSalary(111000);
  28. //將業(yè)務(wù)數(shù)據(jù)對象Employee插入到KnowledgeSession中
  29. session.insert(employee);
  30. //執(zhí)行所有滿足條件的規(guī)則
  31. Map<String,Object> parameter=new HashMap<String,Object>();
  32. parameter.put("count", 10);
  33. parameter.put("result", true);
  34. //觸發(fā)規(guī)則時并設(shè)置參數(shù)
  35. session.fireRules(parameter);
  36. //獲取計算后的result值,要通過KnowledgeSession,而不能通過原來的parameter對象
  37. boolean result=(Boolean)session.getParameter("result");
  38. System.out.println(result);
  39. }
  40. }

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

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

  1. package tt;
  2. import java.util.HashMap;
  3. import java.util.Map;
  4. import rete.test.Dept;
  5. import rete.test.Employee;
  6. import com.bstek.urule.Utils;
  7. import com.bstek.urule.runtime.KnowledgePackage;
  8. import com.bstek.urule.runtime.KnowledgeSession;
  9. import com.bstek.urule.runtime.KnowledgeSessionFactory;
  10. import com.bstek.urule.runtime.service.KnowledgeService;
  11. /**
  12. * @author Jacky.gao
  13. * @since 201535
  14. */
  15. public class Invoke {
  16. public void doTest() throws Exception{
  17. //從Spring中獲取KnowledgeService接口實例
  18. KnowledgeService service=(KnowledgeService)Utils.getApplicationContext().getBean(KnowledgeService.BEAN_ID);
  19. //通過KnowledgeService接口獲取指定的資源包"test123"
  20. KnowledgePackage knowledgePackage=service.getKnowledge("projectName/test123");
  21. //通過取到的KnowledgePackage對象創(chuàng)建KnowledgeSession對象
  22. KnowledgeSession session=KnowledgeSessionFactory.newKnowledgeSession(knowledgePackage);
  23. Employee employee=new Employee();
  24. Dept dept=new Dept();
  25. dept.setLevel(12);
  26. employee.setDept(dept);
  27. employee.setSalary(111000);
  28. //將業(yè)務(wù)數(shù)據(jù)對象Employee插入到KnowledgeSession中
  29. session.insert(employee);
  30. //執(zhí)行所有滿足條件的規(guī)則
  31. Map<String,Object> parameter=new HashMap<String,Object>();
  32. parameter.put("count", 10);
  33. parameter.put("result", true);
  34. //開始規(guī)則流并設(shè)置參數(shù)
  35. session.startProcess("flow-test",parameter);
  36. //獲取計算后的result值,要通過KnowledgeSession,而不能通過原來的parameter對象
  37. boolean result=(Boolean)session.getParameter("result");
  38. System.out.println(result);
  39. }
  40. }

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

批處理支持

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

  1. /**
  2. * 創(chuàng)建一個用于批處理的BatchSession對象,這里默認將開啟10個普通的線程池來運行提交的批處理任務(wù),默認將每100個任務(wù)放在一個線程里處理
  3. * @param knowledgePackage 創(chuàng)建BatchSession對象所需要的KnowledgePackage對象
  4. * @return 返回一個新的BatchSession對象
  5. */
  6. public static BatchSession newBatchSession(KnowledgePackage knowledgePackage){
  7. return new BatchSessionImpl(knowledgePackage,BatchSession.DEFAULT_THREAD_SIZE,BatchSession.DEFAULT_BATCH_SIZE);
  8. }
  9. /**
  10. * 創(chuàng)建一個用于批處理的BatchSession對象,第二個參數(shù)來指定線程池中可用線程個數(shù),默認將每100個任務(wù)放在一個線程里處理
  11. * @param knowledgePackage 創(chuàng)建BatchSession對象所需要的KnowledgePackage對象
  12. * @param threadSize 線程池中可用的線程個數(shù)
  13. * @return 返回一個新的BatchSession對象
  14. */
  15. public static BatchSession newBatchSessionByThreadSize(KnowledgePackage knowledgePackage,int threadSize){
  16. return new BatchSessionImpl(knowledgePackage,threadSize,BatchSession.DEFAULT_BATCH_SIZE);
  17. }
  18. /**
  19. * 創(chuàng)建一個用于批處理的BatchSession對象,這里默認將開啟10個普通的線程池來運行提交的批處理任務(wù),第二個參數(shù)用來決定單個線程處理的任務(wù)數(shù)
  20. * @param knowledgePackage 創(chuàng)建BatchSession對象所需要的KnowledgePackage對象
  21. * @param batchSize 單個線程處理的任務(wù)數(shù)
  22. * @return 返回一個新的BatchSession對象
  23. */
  24. public static BatchSession newBatchSessionByBatchSize(KnowledgePackage knowledgePackage,int batchSize){
  25. return new BatchSessionImpl(knowledgePackage,BatchSession.DEFAULT_THREAD_SIZE,batchSize);
  26. }
  27. /**
  28. * 創(chuàng)建一個用于批處理的BatchSession對象,第二個參數(shù)來指定線程池中可用線程個數(shù),第三個參數(shù)用來決定單個線程處理的任務(wù)數(shù)
  29. * @param knowledgePackage 創(chuàng)建BatchSession對象所需要的KnowledgePackage對象
  30. * @param threadSize 線程池中可用的線程個數(shù)
  31. * @param batchSize 單個線程處理的任務(wù)數(shù)
  32. * @return 返回一個新的BatchSession對象
  33. */
  34. public static BatchSession newBatchSession(KnowledgePackage knowledgePackage,int threadSize,int batchSize){
  35. return new BatchSessionImpl(knowledgePackage,threadSize,batchSize);
  36. }
  37. /**
  38. * 創(chuàng)建一個用于批處理的BatchSession對象,這里默認將開啟10個普通的線程池來運行提交的批處理任務(wù),默認將每100個任務(wù)放在一個線程里處理
  39. * @param knowledgePackage 創(chuàng)建BatchSession對象所需要的KnowledgePackage集合對象
  40. * @return 返回一個新的BatchSession對象
  41. */
  42. public static BatchSession newBatchSession(KnowledgePackage[] knowledgePackages){
  43. return new BatchSessionImpl(knowledgePackages,BatchSession.DEFAULT_THREAD_SIZE,BatchSession.DEFAULT_BATCH_SIZE);
  44. }
  45. /**
  46. * 創(chuàng)建一個用于批處理的BatchSession對象,第二個參數(shù)來指定線程池中可用線程個數(shù),默認將每100個任務(wù)放在一個線程里處理
  47. * @param knowledgePackages 創(chuàng)建BatchSession對象所需要的KnowledgePackage集合對象
  48. * @param threadSize 線程池中可用的線程個數(shù)
  49. * @return 返回一個新的BatchSession對象
  50. */
  51. public static BatchSession newBatchSessionByThreadSize(KnowledgePackage[] knowledgePackages,int threadSize){
  52. return new BatchSessionImpl(knowledgePackages,threadSize,BatchSession.DEFAULT_BATCH_SIZE);
  53. }
  54. /**
  55. * 創(chuàng)建一個用于批處理的BatchSession對象,這里默認將開啟10個普通的線程池來運行提交的批處理任務(wù),第二個參數(shù)用來決定單個線程處理的任務(wù)數(shù)
  56. * @param knowledgePackages 創(chuàng)建BatchSession對象所需要的KnowledgePackage集合對象
  57. * @param batchSize 單個線程處理的任務(wù)數(shù)
  58. * @return 返回一個新的BatchSession對象
  59. */
  60. public static BatchSession newBatchSessionByBatchSize(KnowledgePackage[] knowledgePackages,int batchSize){
  61. return new BatchSessionImpl(knowledgePackages,BatchSession.DEFAULT_THREAD_SIZE,batchSize);
  62. }
  63. /**
  64. * 創(chuàng)建一個用于批處理的BatchSession對象,第二個參數(shù)來指定線程池中可用線程個數(shù),第三個參數(shù)用來決定單個線程處理的任務(wù)數(shù)
  65. * @param knowledgePackages 創(chuàng)建BatchSession對象所需要的KnowledgePackage集合對象
  66. * @param threadSize 線程池中可用的線程個數(shù)
  67. * @param batchSize 單個線程處理的任務(wù)數(shù)
  68. * @return 返回一個新的BatchSession對象
  69. */
  70. public static BatchSession newBatchSession(KnowledgePackage[] knowledgePackages,int threadSize,int batchSize){
  71. return new BatchSessionImpl(knowledgePackages,threadSize,batchSize);
  72. }

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

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

  1. /**
  2. * 添加一個具體要執(zhí)行Business對象
  3. * @param business Business對象實例
  4. */
  5. void addBusiness(Business business);
  6. /**
  7. * 等待線程池中所有業(yè)務(wù)線程執(zhí)行完成,在進行批處理操作時一定要以此方法作為方法調(diào)用結(jié)尾
  8. */
  9. void waitForCompletion();

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

  1. package com.bstek.urule.runtime;
  2. /**
  3. * @author Jacky.gao
  4. * @since 2015929
  5. */
  6. public interface Business {
  7. void execute(KnowledgeSession session);
  8. }

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

  1. //從Spring中獲取KnowledgeService接口實例
  2. KnowledgeService service=(KnowledgeService)Utils.getApplicationContext().getBean(KnowledgeService.BEAN_ID);
  3. //通過KnowledgeService接口獲取指定的資源包"aaa"
  4. KnowledgePackage knowledgePackage=service.getKnowledge("projectName/aaa");
  5. //通過取的KnowledgePackage對象創(chuàng)建BatchSession對象,在這個對象中,我們將開啟5個線程,每個線程最多放置10個Bussiness接口實例運行
  6. BatchSession batchSession=KnowledgeSessionFactory.newBatchSession(knowledgePackage, 5, 10);
  7. for(int i=0;i<100;i++){
  8. batchSession.addBusiness(new Business(){
  9. @Override
  10. public void execute(KnowledgeSession session) {
  11. Employee employee=new Employee();
  12. employee.setSalary(11080);
  13. //將業(yè)務(wù)數(shù)據(jù)對象Employee插入到KnowledgeSession中
  14. session.insert(employee);
  15. session.startProcess("demo");
  16. }
  17. });
  18. }
  19. //等待所有的線程執(zhí)行完成,對于BatchSession調(diào)用來說,此行代碼必不可少,否則將導(dǎo)致錯誤
  20. batchSession.waitForCompletion();
以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號