Activiti工作流學習-----基於5.19.0版本(2)

来源:http://www.cnblogs.com/liujie037/archive/2016/08/18/5778514.html
-Advertisement-
Play Games

二、activiti.cfg.xml的其他bean節點配置 2.1 新特性:Job Executor和Async Executor 從5.17.0版本的activiti開始提供作業執行者(Job Executor)和非同步作業執行者(Async Executor),Async Executor執行表現 ...


二、activiti.cfg.xml的其他bean節點配置

2.1 新特性:Job Executor和Async Executor

從5.17.0版本的activiti開始提供作業執行者(Job Executor)和非同步作業執行者(Async Executor),Async Executor執行表現更好,並且執行非同步作業對資料庫更加友善。activiti官方推薦使用Async Executor,並且一些老的Job Executor依舊有效。在Java EE 7運行環境中,JSR-236規範支持容器管理ManagedJobExecutor和ManagedAsyncJobExecutor,例如可以配置如下:

<bean id="threadFactory" class="org.springframework.jndi.JndiObjectFactoryBean">
   <property name="jndiName" value="java:jboss/ee/concurrency/factory/default" />
</bean>

<bean id="customJobExecutor" class="org.activiti.engine.impl.jobexecutor.ManagedJobExecutor">
   <!-- ... -->
   <property name="threadFactory" ref="threadFactory" />
   <!-- ... -->
</bean>

2.2 激活Job executor

Job executor作為管理多線程執行定時任務的組件,在單元測試場景里,Job executor在多線程中執行是測試不方便的,所以activiti提供了api解決了這個麻煩:

查詢獲取Job executor可以通過ManagementService.createJobQuery方法實現,執行該作業可以調用ManagementService.executeJob,使得在單元測試中Job executor可以被控制,順利關閉Job executor。預設的Job executor是在流程引擎啟動就被激活的,如果需要關閉這個功能,可以配置:

<property name="jobExecutorActivate" value="false" />

2.3 激活Async executor

AsyncExecutor作為管理線程池執行定時任務的組件,預設activiti是關閉AsyncExecutor的,使用它的配置如下:

<property name="asyncExecutorEnabled" value="true" />
<property name="asyncExecutorActivate" value="true" />

asyncExecutorEnabled屬性設置設置true後將代替那些老的Job executor,第二個屬性asyncExecutorActivate是指示activiti在流程引擎啟動就激活AsyncExecutor。

2.4 流程定義緩存配置

所有被解析的流程定義都會被緩存起來,這是因為流程定義是不會改變的,沒有必要多次請求資料庫。預設的activiti是沒有限制緩存數量的,如果需要設置:

<property name="processDefinitionCacheLimit" value="10" />

緩存內部是使用HashMap數據結構和LRU演算法實現的。當然,緩存的數量的設置值最好根據流程定義的總數和正在運行的流程實例使用的流程定義數量決定。你也可以使用自定義的緩存實現類替換內部提供的緩存實現,只需要實現介面org.activiti.engine.impl.persistence.deploy.DeploymentCache,然後配置即可:

<property name="processDefinitionCache">
  <bean class="org.activiti.MyCache" />
</property>

對於自定義緩存實現的緩存數量限制可以設置knowledgeBaseCacheLimit和knowledgeBaseCache屬性。

2.5 日誌

在activiti 5.12的時候,日誌框架使用的是SLF4J,替換掉早前的jdk的日誌工具,現在所有的日誌(activiti, spring, mybatis, …​)都通過SLF4J來輸出日誌,你可以具體的日誌實現。

工作流沒有提供日誌的具體實現jar包在依賴裡面,需要你自己手動添加,如果沒有添加,SLF4J會全程使用NOP-logger,它不會全程記錄所有的日誌的,並且警告沒有被記錄,在Maven中比如添加log4j:

<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-log4j12</artifactId>
</dependency>

activiti-explorer和activiti-rest項目是使用的log4j,activiti項目測試也是使用的log4j記錄日誌。

如果你的類路徑下麵已經有了commons-logging的jar了的話,這時需要commons-logging乾的活交給slf4j,比如要讓spring輸出日誌使用slf4j的話,需要使用依賴:

<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>jcl-over-slf4j</artifactId>
</dependency>

如果使用的伺服器是Tomcat,需要註意tomcat自己的類路徑下麵也有日誌的jar包,解決辦法參考:http://www.slf4j.org/codes.html#release

2.6 日誌配置相關工作流上下文

從版本5.13開始,Activiti支持使用slf4j記錄工作流上下文,日誌通過底層日誌logger記錄的內容有:

  • processDefinition Id ------    mdcProcessDefinitionID

  • processInstance Id  -------   mdcProcessInstanceID

  • execution Id -     ----   mdcexecutionId

日誌記錄有格式化的信息和其他的普通信息,例如日誌記錄可以配置:

 log4j.appender.consoleAppender.layout.ConversionPattern =ProcessDefinitionId=%X{mdcProcessDefinitionID}
executionId=%X{mdcExecutionId} mdcProcessInstanceID=%X{mdcProcessInstanceID} mdcBusinessKey=%X{mdcBusinessKey} %m%n"
在系統關鍵的地方進行記錄或檢測是非常有必要的,通過日誌分析也是其中一種手段。

2.7 事件處理

在Activiti 5.15中引入了事件機制,它讓你在工作流引擎中的各種事件發生時得到消息,activiti能夠支持註冊一個偵聽器對於某些類型的事件而不是任何類型的事件發生時收到通知,一方面可以在配置文件中添加engine-wide事件監聽器配置,然後engine-wide事件監聽器類會調用相應的API,另一方面也可以在在BPMN配置文件中配置。

所有的事件類都是org.activiti.engine.delegate.event.ActivitiEvent的子類,事件會提供type、executionId、processInstanceId和processDefinitionId,某些事件包含了事件發生的上下文,附載入荷的信息。

2.8 事件監聽器的實現

事件監聽器需要實現org.activiti.engine.delegate.event.ActivitiEventListener,例如:

public class MyEventListener implements ActivitiEventListener {

  @Override
  public void onEvent(ActivitiEvent event) {
    switch (event.getType()) {

      case JOB_EXECUTION_SUCCESS:
        System.out.println("A job well done!");
        break;

      case JOB_EXECUTION_FAILURE:
        System.out.println("A job has failed...");
        break;

      default:
        System.out.println("Event received: " + event.getType());
    }
  }

  @Override
  public boolean isFailOnException() {
    // The logic in the onEvent method of this listener is not critical, exceptions
    // can be ignored if logging fails...
    return false;
  }
}
MyEventListener接收標準事件類型並處理和異常處理,其中isFailOnException()決定了onEvent(..)是否拋出異常,如果返回false,異常將會被忽略。如果返回true,異常將會逐級向上提交,
造成當前運行的命令的失敗。如果當前執行具有事務,事務將會回滾。activiti官方建議如果事件的業務不是非常重要,還是返回false。
activiti提供了通用的實現類來處理普通的事件監聽,例如:
org.activiti.engine.delegate.event.BaseEntityEventListener:它將會監聽entity類的事件,它隱藏了類型檢查和重寫了四個方法,onCreate(..), onUpdate(..)和onDelete(..),
對於其他的事件,onEntityEvent(..)將會被調用。

2.9 事件的相關配置

如果一個事件監聽器在流程引擎配置,流程引擎啟動將會激活,即使重啟引擎也會保持該狀態。eventListeners屬性值為org.activiti.engine.delegate.event.ActivitiEventListener
的實例的list,例如:
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
    ...
    <property name="eventListeners">
      <list>
         <bean class="org.activiti.engine.example.MyEventListener" />
      </list>
    </property>
</bean>
另外typedEventListeners屬性值為Map,key為事件的名稱,value表示為一個org.activiti.engine.delegate.event.ActivitiEventListener的list集合,例如:
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
    ...
    <property name="typedEventListeners">
      <map>
        <entry key="JOB_EXECUTION_SUCCESS,JOB_EXECUTION_FAILURE" >
          <list>
            <bean class="org.activiti.engine.example.MyJobEventListener" />
          </list>
        </entry>
      </map>
    </property>
</bean>

事件發生的順序取決於被配置的監聽器的順序。首先,所有的普通的監聽器會被調用(也就是說eventListeners屬性,至於eventListeners的內部的監聽器順序和配置的順序有關)

,然後是在typedListeners屬性配置的會被調用。

2.10 程式運行時動態添加監聽器

調用RuntimeService的api方法可以實現這個功能:(註意:系統重啟會導致監聽器消失)
void addEventListener(ActivitiEventListener listenerToAdd);

void addEventListener(ActivitiEventListener listenerToAdd, ActivitiEventType... types);

void removeEventListener(ActivitiEventListener listenerToRemove);

2.11 添加監聽器到流程定義中

在流程定義中添加監聽器是允許的,這裡定義的監聽器會被流程定義相關的事件和所有的相關的流程實例啟動後調用,監聽器的實現類可以使用全類名、能夠被解析為bean的表達式。例如下麵這個配置,第一個監聽器將接收所有的事件,它使用的是全類名進行配置的,第二個監聽器僅僅是在作業執行成功或者失敗會被執行,並且使用了在流程引擎中定義的beans屬性配置的監聽器的表達式。

 

<process id="testEventListeners">
  <extensionElements>
    <activiti:eventListener class="org.activiti.engine.test.MyEventListener" />
    <activiti:eventListener delegateExpression="${testEventListener}" events="JOB_EXECUTION_SUCCESS,JOB_EXECUTION_FAILURE" />
  </extensionElements>
  ...
</process>

 如果我們需要在流程定義中配置監聽entity的監聽器的話,可以這樣配置:

<process id="testEventListeners">
  <extensionElements>
    <activiti:eventListener class="org.activiti.engine.test.MyEventListener" entityType="task" />
    <activiti:eventListener delegateExpression="${testEventListener}" events="ENTITY_CREATED" entityType="task" />
  </extensionElements>
  ...
</process>

其中entityType的值有:attachment, comment, execution, identity-link, job, process-instance, process-definition, task。

 

 

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 非同步編程:使用線程池管理線程 從此圖中我們會發現 .NET 與C# 的每個版本發佈都是有一個“主題”。即:C#1.0托管代碼→C#2.0泛型→C#3.0LINQ→C#4.0動態語言→C#5.0非同步編程。現在我為最新版本的“非同步編程”主題寫系列分享,期待你的查看及點評。 如今的應用程式越來越複雜,我們 ...
  • 更新具體細節參見:[更新設計]跨平臺物聯網通訊框架ServerSuperIO 2.0 ,功能、BUG、細節說明,以及升級思考過程! 聲明:公司在建設工業大數據平臺,SSIO正好能派上用場,所以抓緊時間進行了完善,並且升級到了2.0版本,希望對大家有幫助。僅供開源學習,商用請聯繫作者。 1.SSIO特 ...
  • 在C#實現類似Typedef的所有功能 Typedef這個關鍵字,是比較好用的東西,因為有時候我們需要使用一些別名來幫助我們記憶某些結構體或者類的共用。(個人覺得這是C與C++唯一能吸引我的東西)為了能夠實現這個想法,我們可以使用下列方法。 1.使用using語句進行別名,這個方法適合針對結構體。 ...
  • ASP.NET Boilerplate,簡稱ABP 詳細深入:可以參考如下文章 http://www.cnblogs.com/mienreal/p/4528470.html http://www.cnblogs.com/farb/ 開始前你將要跑起第一個abp程式 可是發現怎麼都運行不起來。。。。 ...
  • 最前面的話:Smobiler是一個在VS環境中使用.Net語言來開發APP的開發平臺,也許比Xamarin更方便 ...
  • 如題,要實現一個如下的列表,該如何實現? 在設計過程中,會遇到如下問題: 1、ListBox中ListBoxItem的模板設計 2、ListBox中ListBoxItem的模板容器設計 3、ListBox本身的模板設計 4、ListBox本身的焦點樣式 下麵我們依次來解決這些問題: 1、子模板 2、 ...
  • 前端: 後端: ...
  • C#過濾html標簽 在項目中遇到這樣一個需求,需要將一段html轉換為一般文本返回,萬能的正則表達式來了。 正則表達式來拯救你,代碼如下: 1 public static string Html2Text(string htmlStr) 2 3 { 4 5 if (String.IsNullOrE ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...