Activiti工作流框架中任務流程元素詳解!使用任務元素進行任務的調度和執行

      網友投稿 2264 2025-04-01

      任務

      用戶任務

      用戶任務用來設置必須由人員完成的工作

      當流程執行到用戶任務,會創建一個新任務,并把這個新任務加入到分配人或群組的任務列表中

      用戶任務顯示成一個普通任務(圓角矩形),左上角有一個小用戶圖標

      XML中的用戶任務定義:id屬性是必須的,name屬性是可選的:

      用戶任務可以設置描述,添加documentation元素可以定義描述:

      Schedule an engineering meeting for next week with the new hire.

      描述文本可以通過標準的java方法來獲取:

      task.getDescription()

      任務可以用一個字段來描述任務的持續時間

      可以使用查詢API來對持續時間進行搜索,根據在時間之前或之后進行搜索

      Activiti提供了一個節點擴展,在任務定義中設置一個表達式,這樣在任務創建時就可以設置初始持續時間

      表達式應該是:

      java.util.Date

      java.util.String(ISO8601格式),ISO8601持續時間(比如PT50M)

      null

      在流程中使用上述格式輸入日期,或在前一個服務任務中計算一個時間.這里使用了持續時間,持續時間會基于當前時間進行計算,再通過給定的時間段累加: 使用"PT30M"作為持續時間,任務就會從現在開始持續30分鐘

      任務的持續時間也可以通過TaskService修改,或在TaskListener中通過傳入的DelegateTask參數修改

      用戶任務可以直接分配給一個用戶,通過humanPerformer元素定義

      humanPerformer定義需要一個resourceAssignmentExpression來實際定義用戶.目前只支持formalExpressions

      ... kermit

      只有一個用戶可以作為任務的執行者分配用戶

      在activiti中,用戶叫做執行者

      擁有執行者的用戶不會出現在其他人的任務列表中,只能出現執行者的個人任務列表中

      直接分配給用戶的任務可以通過TaskService獲取:

      List tasks = taskService.createTaskQuery().taskAssignee("kermit").list();

      任務也可以加入到人員的候選任務列表中.需要使用potentialOwner元素

      用法和humanPerformer元素類似**,需要指定表達式中的每個項目是人員還是群組**

      ... user(kermit), group(management)

      使用potentialOwner元素定義的任務可以通過TaskService獲取:

      List tasks = taskService.createTaskQuery().taskCandidateUser("kermit");

      這會獲取所有kermit為候選人的任務,表達式中包含user(kermit).這也會獲得所有分配包含kermit這個成員的群組(比如,group(management),前提是kermit是這個組的成員,并且使用了activiti的賬號組件).用戶所在的群組是在運行階段獲取的, 它們可以通過IdentityService進行管理

      如果沒有顯式指定設置的是用戶還是群組,引擎會默認當做群組處理

      下面的設置與使用group(accountancy)一樣:

      accountancy

      當分配不復雜時,用戶和組的設置非常麻煩.為避免復雜性,可以使用用戶任務的自定義擴展

      assignee屬性: 直接把用戶任務分配給指定用戶(和使用humanPerformer 效果完全一樣)

      candidateUsers屬性: 為任務設置候選人(和使用potentialOwner效果完全一樣,不需要像使用potentialOwner通過user(kermit)聲明,這個屬性只能用于人員)

      candidateGroups屬性: 為任務設置候選組(和使用potentialOwner效果完全一樣,不需要像使用potentialOwner通過group(management)聲明,這個屬性只能用于群組)

      candidateUsers和candidateGroups可以同時設置在同一個用戶任務中

      Activiti中雖然有賬號管理組件和IdentityService ,賬號組件不會檢測設置的用戶是否存在. Activiti允許與其他已存的賬戶管理方案集成

      使用創建事件的任務- 來實現自定義的分配邏輯:

      DelegateTask會傳遞給TaskListener的實現,通過它可以設置執行人,候選人和候選組

      public class MyAssignmentHandler implements TaskListener { public void notify(DelegateTask delegateTask) { // Execute custom identity lookups here // and then for example call following methods: delegateTask.setAssignee("kermit"); delegateTask.addCandidateUser("fozzie"); delegateTask.addCandidateGroup("management"); ... } }

      使用spring時,使用表達式把任務-設置為spring代理的bean,讓這個-監聽任務的創建事件

      示例:執行者會通過調用ldapService這個spring bean的findManagerOfEmployee方法獲得.流程變量emp會作為參數傳遞給bean

      可以用來設置候選人和候選組:

      方法返回類型只能為String(候選人) 或Collection < String >(候選組):

      public class FakeLdapService { public String findManagerForEmployee(String employee) { return "Kermit The Frog"; } public List findAllSales() { return Arrays.asList("kermit", "gonzo", "fozzie"); } }

      腳本任務

      腳本任務是一個自動節點

      當流程到達腳本任務,會執行對應的腳本

      腳本任務顯示為標準BPMN 2.0任務(圓角矩形),左上角有一個腳本小圖標

      腳本任務定義需要指定script和scriptFormat

      scriptFormat的值必須兼容JSR-223(java平臺的腳本語言).默認Javascript會包含在JDK中,不需要額外的依賴.如果要使用其他的腳本引擎,必須要是JSR-223引擎兼容的.還需要把對應的jar添加到classpath下, 并使用合適的名稱:activiti單元測試經常使用groovy

      groovy腳本引擎放在groovy-all.jar中,在2.0版本之前,腳本引擎是groovy jar的一部分.使用需要添加依賴:

      org.codehaus.groovy groovy-all 2.x.x

      到達腳本任務的流程可以訪問的所有流程變量,都可以在腳本中使用

      也可以在腳本中設置流程變量,直接調用execution.setVariable(“variableName”, variableValue)

      默認,不會自動保存變量(activiti 5.12之前)

      可以在腳本中自動保存任何變量,只要把scriptTask的autoStoreVariables屬性設置為true

      最佳實踐是不要使用,而是顯式調用execution.setVariable()

      參數默認為false: 如果沒有為腳本任務定義設置參數,所有聲明的變量將只存在于腳本執行的階段

      在腳本中設置變量: 這些命名已經被占用,不能用作變量名- out, out:print, lang:import, context, elcontext.

      腳本任務的返回值可以通過制定流程變量的名稱,分配給已存在或者一個新流程變量,需要使用腳本任務定義的’activiti:resultVariable’屬性

      任何已存在的流程變量都會被腳本執行的結果覆蓋

      如果沒有指定返回的變量名,腳本的返回值會被忽略

      腳本的結果-表達式 #{echo} 的值會在腳本完成后,設置到myVar變量中

      Java服務任務

      Java服務任務用來調用外部Java類

      Java服務任務顯示為圓角矩形,左上角有一個齒輪小圖標

      聲明Java調用邏輯有四種方式:

      實現JavaDelegate或者ActivityBehavior

      執行解析代理對象的表達式

      調用一個方法表達式

      調用一個值表達式

      執行一個在流程執行中調用的類,需要在activiti:class屬性中設置全類名:

      使用表達式調用一個對象,對象必須遵循一些規則,并使用activiti:delegateExpression屬性進行創建:

      delegateExpressionBean是一個實現了JavaDelegate接口的bean,定義在實例的spring容器中

      要執行指定的UEL方法表達式, 需要使用activiti:expression:

      方法printMessage()會調用名為printer對象的方法

      為表達式中的方法傳遞參數:

      調用名為printer對象上的方法printMessage.第一個參數是DelegateExecution, 在表達式環境中默認名稱為execution. 第二個參數傳遞的是當前流程的名為myVar的變量

      要執行指定的UEL方法表達式, 需要使用activiti:expression:

      ready屬性的getter方法:getReady() 會作用于名為split的bean上.這個對象會被解析為流程對象和spring環境中的對象

      要在流程執行中實現一個調用的類,這個類需要實現org.activiti.engine.delegate.JavaDelegate接口,并在execute方法中提供對應的業務邏輯.當流程執行到特定階段,會指定方法中定義好的業務邏輯,并按照默認BPMN 2.0中的方式離開節點

      示例:

      創建一個java類的例子,對流程變量中字符串轉換為大寫

      這個類需要實現org.activiti.engine.delegate.JavaDelegate接口,要求實現execute(DelegateExecution) 方法,包含的業務邏輯會被引擎調用

      流程實例信息:流程變量和其他信息,可以通過DelegateExecution接口訪問和操作

      public class ToUppercase implements JavaDelegate { public void execute(DelegateExecution execution) throws Exception { String var = (String) execution.getVariable("input"); var = var.toUpperCase(); execution.setVariable("input", var); } }

      serviceTask定義的class只會創建一個java類的實例

      所有流程實例都會共享相同的類實例,并調用execute(DelegateExecution)

      類不能使用任何成員變量,必須是線程安全的,必須能模擬在不同線程中執行.影響著屬性注入的處理方式

      流程定義中引用的類(activiti:class)不會在部署時實例化

      只有當流程第一次執行到使用類的時候,類的實例才會被創建

      如果找不到類,會拋出一個ActivitiException

      這個原因是部署環境(更確切是的classpath)和真實環境往往是不同的:當使用ant或業務歸檔上傳到Activiti Explorer來發布流程,classpath沒有包含引用的類

      內部實現類也可以提供實現org.activiti.engine.impl.pvm.delegate.ActivityBehavior接口的類

      實現可以訪問更強大的ActivityExecution,它可以影響流程的流向

      注意: 這應該盡量避免.只有在高級情況下并且確切知道要做什么的情況下,再使用ActivityBehavior接口

      為代理類的屬性注入數據. 支持如下類型的注入:

      固定的字符串

      表達式

      如果有效的話,數值會通過代理類的setter方法注入,遵循java bean的命名規范(比如fistName屬性對應setFirstName(Xxx)方法)

      如果屬性沒有對應的setter方法,數值會直接注入到私有屬性中

      一些環境的SecurityManager不允許修改私有屬性,要把想注入的屬性暴露出對應的setter方法來

      無論流程定義中的數據是什么類型,注入目標的屬性類型都應該是 org.activiti.engine.delegate.Expression

      示例:

      把一個常量注入到屬性中

      屬性注入可以使用class屬性

      在聲明實際的屬性注入之前,需要定義一個extensionElements的XML元素

      ToUpperCaseFieldInjected類有一個text屬性,類型是org.activiti.engine.delegate.Expression. 調用text.getValue(execution) 時,會返回定義的字符串Hello World

      可以使用長文字(比如,內嵌的email),使用activiti:string子元素:

      Hello World

      可以使用表達式,實現在運行期動態解析注入的值

      這些表達式可以使用流程變量或spring定義的bean.

      服務任務中的java類實例會在所有流程實例中共享:

      為了動態注入屬性的值,可以在org.activiti.engine.delegate.Expression中使用值和方法表達式

      會使用傳遞給execute方法的DelegateExecution參數進行解析

      ${genderBean.getGenderString(gender)} Hello ${gender == 'male' ? 'Mr.' : 'Mrs.'} ${name}

      示例:

      注入表達式,并使用在當前傳入的DelegateExecution解析:

      public class ReverseStringsFieldInjected implements JavaDelegate { private Expression text1; private Expression text2; public void execute(DelegateExecution execution) { String value1 = (String) text1.getValue(execution); execution.setVariable("var1", new StringBuffer(value1).reverse().toString()); String value2 = (String) text2.getValue(execution); execution.setVariable("var2", new StringBuffer(value2).reverse().toString()); } }

      可以把表達式設置成一個屬性,而不是子元素:

      因為java類實例會被重用,注入只會發生一次,當服務任務調用第一次的時候發生注入

      當代碼中的屬性改變了,值也不會重新注入,把它們看作是不變的,不用修改它們

      服務流程返回的結果(使用表達式的服務任務)可以分配給已經存在的或新的流程變量

      通過指定服務任務定義的activiti:resultVariable屬性來實現

      指定的流程變量會被服務流程的返回結果覆蓋

      如果沒有指定返回變量名,就會忽略返回結果

      服務流程的返回值(在myService上調用doSomething() 方法的返回值,myService可能是流程變量,也可能是spring的bean),在服務執行完成之后,會設置到名為myVar的流程變量里

      執行自定義邏輯時,常常需要捕獲對應的業務異常,在流程內部進行處理

      拋出BPMN Errors:

      在服務任務或腳本任務的代碼里拋出BPMN error:

      要從JavaDelegate,腳本,表達式和代理表達式中拋出名為BpmnError的特殊ActivitiExeption

      引擎會捕獲這個異常,把它轉發到對應的錯誤處理中:邊界錯誤事件或錯誤事件子流程

      public class ThrowBpmnErrorDelegate implements JavaDelegate { public void execute(DelegateExecution execution) throws Exception { try { executeBusinessLogic(); } catch (BusinessException e) { throw new BpmnError("BusinessExceptionOccured"); } } }

      構造參數是錯誤代碼,會被用來決定哪個錯誤處理器會來響應這個錯誤

      這個機制只用于業務失敗,應該被流程定義中設置的邊界錯誤事件或錯誤事件子流程處理. 技術上的錯誤應該使用其他異常類型,通常不會在流程里處理

      異常順序流:

      內部實現類在一些異常發生時,讓流程進入其他路徑

      這里的服務任務有兩個外出順序流:分別叫exception和no-exception. 異常出現時會使用順序流的ID來決定流向

      public class ThrowsExceptionBehavior implements ActivityBehavior { public void execute(ActivityExecution execution) throws Exception { String var = (String) execution.getVariable("var"); PvmTransition transition = null; try { executeLogic(var); transition = execution.getActivity().findOutgoingTransition("no-exception"); } catch (Exception e) { transition = execution.getActivity().findOutgoingTransition("exception"); } execution.take(transition); } }

      需要在Java服務任務中使用Activiti服務的場景: 比如,通過RuntimeService啟動流程實例,而callActivity不滿足需求

      org.activiti.engine.delegate.DelegateExecution允許通過 org.activiti.engine.EngineServices接口直接獲得這些服務:

      public class StartProcessInstanceTestDelegate implements JavaDelegate { public void execute(DelegateExecution execution) throws Exception { RuntimeService runtimeService = execution.getEngineServices().getRuntimeService(); runtimeService.startProcessInstanceByKey("myProcess"); } }

      所有activiti服務的API都可以通過這個接口獲得

      使用這些API調用出現的所有數據改變,都是在當前事務中

      在例如spring和CDI這樣的依賴注入環境也會起作用,無論是否啟用了JTA數據源

      示例: 下面的代碼功能與上面的代碼一致,這是RuntimeService是通過依賴注入獲得,而不是通過org.activiti.engine.EngineServices接口

      @Component("startProcessInstanceDelegate") public class StartProcessInstanceTestDelegateWithInjection { @Autowired private RuntimeService runtimeService; public void startProcess() { runtimeService.startProcessInstanceByKey("oneTaskProcess"); } }

      因為服務調用是在當前事務里,數據的產生或改變,在服務任務執行完之前,還沒有提交到數據庫.所以API對于數據庫數據的操作,意味著未提交的操作在服務任務的API調用中都是不可見的

      WebService任務

      WebService任務可以用來同步調用一個外部的WebService

      WebService任務與Java服務任務顯示效果一樣(圓角矩形,左上角有一個齒輪小圖標)

      要使用WebService需要導入操作和類型,可以使用import標簽來指定WebService的WSDL

      聲明告訴activiti導入WSDL定義,但沒有創建itemDefinition和message

      假設想調用一個名為prettyPrint的方法,必須創建為請求和響應信息對應的message和itemDefinition

      在申請服務任務之前,必須定義實際引用WebService的BPMN接口和操作

      基本上,定義接口和必要的操作.對每個操作都會重用上面定義的信息作為輸入和輸出

      示例:

      定義了counter接口和prettyPrintCountOperation操作:

      tns:prettyPrintCountRequestMessage tns:prettyPrintCountResponseMessage

      然后定義WebService任務,使用WebService實現,并引用WebService操作

      每個WebService任務可以定義任務的輸入輸出IO規范

      dataInputOfServiceTask dataOutputOfServiceTask

      指定數據輸入關聯有兩種方式:

      使用表達式

      使用簡化方式

      使用表達式指定數據輸入關聯: 需要定義來源和目的item,并指定每個item屬性之間的對應關系:

      dataInputOfProcess dataInputOfServiceTask ${dataInputOfProcess.prefix} ${dataInputOfServiceTask.prefix} ${dataInputOfProcess.suffix} ${dataInputOfServiceTask.suffix}

      分配item的前綴和后綴

      使用簡化方式指定數據輸入關聯: sourceRef元素是activiti的變量名,targetRef元素是item定義的一個屬性:

      PrefixVariable prefix SuffixVariable suffix

      PrefixVariable變量的值分配給prefix屬性,把SuffixVariable變量的值分配給suffix屬性

      指定數據輸出關聯有兩種方式:

      使用表達式

      使用簡化方式

      使用表達式指定數據輸出關聯: 需要定義目的變量和來源表達式

      dataOutputOfProcess ${dataOutputOfServiceTask.prettyPrint}

      Activiti工作流框架中任務流程元素詳解!使用任務元素進行任務的調度和執行

      方法和數據輸入關聯完全一樣

      使用簡化方式指定數據輸出關聯: sourceRef元素是item定義的一個屬性,targetRef元素是activiti的變量名

      prettyPrint OutputVariable

      方法和數據輸入關聯完全一樣

      業務規則任務

      業務規則任務用來同步執行一個或多個規則

      Activiti使用drools規則引擎執行業務規則:

      包含業務規則的.drl文件必須和流程定義一起發布

      流程定義里包含了執行這些規則的業務規則任務

      流程使用的所有.drl文件都必須打包在流程BAR文件里

      如果想要自定義規則任務的實現: 想用不同方式使用drools,或者使用完全不同的規則引擎.你可以使用BusinessRuleTask上的class或表達式屬性

      業務規則任務是一個圓角矩形,左上角使用一個表格小圖標進行顯示

      要執行部署流程定義的BAR文件中的一個或多個業務規則,需要定義輸入和輸出變量:

      對于輸入變量定義,可以使用逗號分隔的一些流程變量

      輸出變量定義只包含一個變量名,會把執行業務規則后返回的對象保存到對應的流程變量中

      注意: 結果變量會包含一個對象列表,如果沒有指定輸出變量名稱,默認會使用 org.activiti.engine.rules.OUTPUT

      業務規則任務也可以配置成只執行部署的.drl文件中的一些規則.這時要設置逗號分隔的規則名,只會執行rule1和rule2:

      定義哪些規則不用執行:除了rule1和rule2以外,所有部署到流程定義同一個BAR文件中的規則都會執行:

      可以用一個選項修改BusinessRuleTask的實現:

      BusinessRuleTask的功能和ServiceTask一樣,但是使用BusinessRuleTask的圖標來表示 在這里要執行業務規則

      郵件任務

      Activiti強化了業務流程,支持自動郵件任務:

      可以發送郵件給一個或多個參與者,包括支持cc,bcc,HTML內容等等

      郵件任務不是BPMN 2.0規范定義的官方任務,Activiti中郵件任務是用專門的服務任務實現的

      Activiti引擎要通過支持SMTP功能的外部郵件服務器發送郵件

      為了實際發送郵件,引擎穾知道如何訪問郵件服務器.下面的配置可以設置到activiti.cfg.xml配置文件中:

      郵件任務是一個專用的服務任務, 這個服務任務的type設置為mail

      郵件任務是通過屬性注入進行配置的.所有這些屬性都可以使用EL表達式,可以在流程執行中解析. 下面的屬性都可以設置:

      郵件任務的使用示例:

      Hello ${male ? 'Mr.' : 'Mrs.' } ${recipientName},

      As of ${now}, your order has been processed and shipped.

      Kind regards,
      TheCompany. ]]>

      Mule任務

      Mule任務可以向Mule發送消息,用來強化Activiti的集成能力

      Mule任務不是BPMN 2.0規范定義的官方任務,Activiti中Mule任務是用專門的服務任務實現的

      Mule任務是一個專用的服務任務, 服務任務的type設置為mule

      Mule任務是通過屬性注入進行配置的.屬性使用EL表達式, 可以在流程執行中解析

      Mule任務的使用示例:

      vm://in juel "hi" theVariable

      Java Spring

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      版權聲明:本文內容由網絡用戶投稿,版權歸原作者所有,本站不擁有其著作權,亦不承擔相應法律責任。如果您發現本站中有涉嫌抄襲或描述失實的內容,請聯系我們jiasou666@gmail.com 處理,核實后本網站將在24小時內刪除侵權內容。

      上一篇:Excel利用VBA比較同行字符串一例
      下一篇:資料管理業務流程,如何有效管理您的數據
      相關文章
      亚洲AV无码一区二区三区性色 | 亚洲福利视频导航| 亚洲国产精品激情在线观看| 亚洲成a∧人片在线观看无码| 亚洲熟妇AV一区二区三区宅男| 亚洲一级毛片在线播放| 亚洲国产成人va在线观看网址| 亚洲精品美女在线观看| 亚洲性天天干天天摸| 蜜芽亚洲av无码精品色午夜| 亚洲天堂中文字幕| 亚洲黄色一级毛片| 亚洲免费视频观看| 456亚洲人成影院在线观| 精品亚洲456在线播放| 中文字幕亚洲情99在线| 亚洲欧美日韩综合久久久久| 亚洲av无码专区青青草原| 亚洲AV日韩AV永久无码色欲| 麻豆亚洲AV成人无码久久精品| 亚洲AV无码专区在线厂| 亚洲Av无码乱码在线观看性色| 亚洲乱码中文字幕综合234| 国产亚洲欧洲Aⅴ综合一区| 亚洲中文字幕在线观看| 亚洲av无码潮喷在线观看| 久久亚洲美女精品国产精品| 亚洲国产一区在线观看| 亚洲一区二区三区高清在线观看 | 亚洲精品色午夜无码专区日韩| 亚洲精品无码专区久久久| 久久久久亚洲AV成人无码网站| 亚洲午夜久久久精品影院| 亚洲婷婷综合色高清在线| 精品久久久久久亚洲精品| 亚洲精品国产精品| 亚洲第一网站男人都懂| 亚洲精品成人网站在线观看| 久久久久亚洲av无码专区导航 | 亚洲欧洲精品成人久久奇米网| 亚洲熟妇av一区二区三区漫画|