新API的目的很明確,以知足下列需求:java
還沒有棄用舊的API,所以仍然能夠自由使用它,可是強烈建議使用新的API以得到長期支持。git
該API處於Beta測試階段,這意味着可能會在GA發佈以前對其進行更改和完善。github
若是要構建業務應用程序,那麼爲組織中的用戶和組建立任務可能會很方便。web
TaskRuntime API在這裏能夠爲你提供幫助。spring
能夠從GitHub克隆此示例:https://github.com/Activiti/activiti-examples。數據庫
該部分的代碼能夠在「activiti-api-basic-task-example」 maven模塊中找到。api
若是你在Spring Boot 2應用程序中運行,則只需添加activiti-spring-boot-starter依賴項和一個數據庫驅動程序,便可將H2用於內存中存儲。數組
<dependency> <groupId>org.activiti</groupId> <artifactId>activiti-spring-boot-starter</artifactId> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> </dependency>
建議使用BOM。app
<dependencyManagement> <dependencies> <dependency> <groupId>org.activiti.dependencies</groupId> <artifactId>activiti-dependencies</artifactId> <version>7.1.0.M5</version> <scope>import</scope> <type>pom</type> </dependency> </dependencies> </dependencyManagement>
注意:可使用如下連接檢索最新版本: https://search.maven.org/search?q=activiti-dependencies
如今,切換到DemoApplication.class
:https://github.com/Activiti/activiti-examples/blob/master/activiti-api-basic-task-example/src/main/java/org/activiti/examples/DemoApplication.java#L25
而後,你將可使用TaskRuntime
:
@Autowired private TaskRuntime taskRuntime;
將bean注入應用程序後,你應該可以建立任務並與任務交互。
public interface TaskRuntime { TaskRuntimeConfiguration configuration(); Task task(String taskId); Page tasks(Pageable pageable); Page tasks(Pageable pageable, GetTasksPayload payload); Task create(CreateTaskPayload payload); Task claim(ClaimTaskPayload payload); Task release(ReleaseTaskPayload payload); Task complete(CompleteTaskPayload payload); Task update(UpdateTaskPayload payload); Task delete(DeleteTaskPayload payload); ... }
例如,你能夠經過執行如下操做來建立任務:
taskRuntime.create( TaskPayloadBuilder.create() .withName("First Team Task") .withDescription("This is something really important") .withGroup("activitiTeam") .withPriority(10) .build());
只有屬於activitiTeam的用戶和全部者(當前登陸的用戶)才能看到此任務。
你可能已經注意到,可使用TaskPayloadBuilder
以流暢的方式參數化將要發送到TaskRuntime
的信息。
爲了處理安全性、角色和組,依賴於Spring Security模塊。由於在Spring Boot應用程序內部,因此可使用UserDetailsService
來配置可用用戶及其各自的組和角色,目前在@Configuration
類中執行此操做:
這裏須要注意的重要一點是,爲了做爲用戶與TaskRuntime API進行交互,你須要擁有角色:ACTIVITI_USER(授予的權限:ROLEACTIVITIUSER)。
與REST端點進行交互時,受權機制將設置當前登陸的用戶,可是爲了這個例子,使用了一個工具類(https://github.com/Activiti/activiti-examples/blob/master/activiti-api-basic-task-example/src/main/java/org/activiti/examples/SecurityUtil.java#L26),容許在上下文中設置手動選擇的用戶。請注意,除非你正在嘗試而且想要在不通過REST端點的狀況下更改用戶,不然切勿這樣作。查看「web」示例,以查看根本不須要該實用工具類的更多真實場景。
該示例中要強調的最後一件事是任務事件偵聽器的註冊:
@Bean public TaskRuntimeEventListener taskAssignedListener() { return taskAssigned -> logger.info( ">>> Task Assigned: '" + taskAssigned.getEntity().getName() +"' We can send a notification to the assignee: " + taskAssigned.getEntity().getAssignee()); }
你能夠根據須要註冊任意多個TaskRuntimeEventListener,當服務觸發運行時事件時,這將使你的應用程序獲得通知。
以相似的方式,若是要開始使用ProcessRuntime API,則須要包含與以前相同的依賴項,目標是在未來提供更大的靈活性和單獨的運行時,可是目前,相同的Spring Boot Starter同時提供TaskRuntime和ProcessRuntime API。
該部分的代碼能夠在「activiti-api-basic-process-example」 maven模塊內找到。
public interface ProcessRuntime { ProcessRuntimeConfiguration configuration(); ProcessDefinition processDefinition(String processDefinitionId); Page processDefinitions(Pageable pageable); Page processDefinitions(Pageable pageable, GetProcessDefinitionsPayload payload); ProcessInstance start(StartProcessPayload payload); Page processInstances(Pageable pageable); Page processInstances(Pageable pageable, GetProcessInstancesPayload payload); ProcessInstance processInstance(String processInstanceId); ProcessInstance suspend(SuspendProcessPayload payload); ProcessInstance resume(ResumeProcessPayload payload); ProcessInstance delete(DeleteProcessPayload payload); void signal(SignalPayload payload); ... }
與TaskRuntime API類似,爲了與ProcessRuntime API進行交互,當前登陸的用戶必須具備「ACTIVITI_USER」角色。
首先,注入ProcessRuntime
:
@Autowired private ProcessRuntime processRuntime; @Autowired private SecurityUtil securityUtil;
和以前同樣,咱們須要SecurityUtil
幫助器來定義與API交互的用戶。
如今,能夠開始與ProcessRuntime進行交互了:
Page processDefinitionPage = processRuntime .processDefinitions(Pageable.of(0, 10)); logger.info("> Available Process definitions: " + processDefinitionPage.getTotalItems()); for (ProcessDefinition pd : processDefinitionPage.getContent()) { logger.info("\t > Process definition: " + pd); }
流程定義須要放在/src/main/resources/processes/中,在此示例中,定義瞭如下流程:
使用Spring Scheduling功能來每秒啓動一個流程,從數組中拾取隨機值以進行處理:
@Scheduled(initialDelay = 1000, fixedDelay = 1000) public void processText() { securityUtil.logInAs("system"); String content = pickRandomString(); SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yy HH:mm:ss"); logger.info("> Processing content: " + content + " at " + formatter.format(new Date())); ProcessInstance processInstance = processRuntime .start(ProcessPayloadBuilder .start() .withProcessDefinitionKey("categorizeProcess") .withProcessInstanceName("Processing Content: " + content) .withVariable("content", content) .build()); logger.info(">>> Created Process Instance: " + processInstance); }
與以前同樣,使用ProcessPayloadBuilder以流暢的方式參數化咱們但願啓動哪一個流程,以及使用哪一個流程變量。
如今,若是咱們回顧一下流程定義,你將發現3個服務任務,爲了提供這些服務任務的實現,你須要定義Connector
:
@Bean public Connector processTextConnector() { return integrationContext -> { Map inBoundVariables = integrationContext.getInBoundVariables(); String contentToProcess = (String) inBoundVariables.get("content") // Logic Here to decide if content is approved or not if (contentToProcess.contains("activiti")) { logger.info("> Approving content: " + contentToProcess); integrationContext.addOutBoundVariable("approved",true); } else { logger.info("> Discarding content: " + contentToProcess); integrationContext.addOutBoundVariable("approved",false); } return integrationContext; }; }
這些鏈接器使用Bean名稱(在此示例中爲「processTextConnector」)自動鏈接到ProcessRuntime
,此bean名稱是從流程定義內的serviceTask元素的implementation屬性中選取的:
<bpmn:serviceTask id="Task_1ylvdew" name="Process Content" implementation="processTextConnector">
這個新的Connector
接口是JavaDelegate
的天然演變,新版本的Activiti Core將經過將它們包裝在Connector
實現中來嘗試重用JavaDelagate
:
public interface Connector { IntegrationContext execute(IntegrationContext integrationContext); }
鏈接器接收帶有流程變量的IntegrationContext
,並返回修改後的IntegrationContext
,其結果須要映射回流程變量。
在前面的示例中,鏈接器實現正在接收「content」變量,並基於內容處理邏輯添加「approved」變量。
在這些鏈接器內,你可能會包含系統到系統的調用,例如REST調用和基於消息的交互。
查看Maven模塊activiti-api-spring-integration-example以獲取更高級的示例,該示例使用Spring Integrations基於文件輪詢器啓動流程。
你能夠找到使用ProcessRuntime
和TaskRuntime
API來自動執行如下流程的示例:
該部分的代碼能夠在「activiti-api-basic-full-example」 maven模塊內找到。
做爲僅ProcessRuntime
的示例,它還對一些輸入內容進行了分類,可是在這種狀況下,該過程依賴於人工來決定是否批准內容。與以前同樣,有一個調度任務,該任務每5秒建立一個新的流程實例,而且模擬用戶檢查是否有可用的任務要處理。
和
將UserTask建立給一個potentialOwner,在本示例中爲「activitiTeam」組,可是在這種狀況下,咱們不會像第一個示例那樣手動建立任務,每次啓動流程時,流程實例都會爲咱們建立任務。
<bpmn:userTask id="Task_1ylvdew" name="Process Content"> <bpmn:incoming>SequenceFlow_09xowo4</bpmn:incoming> <bpmn:outgoing>SequenceFlow_1jzbgkj</bpmn:outgoing> <bpmn:potentialOwner> <bpmn:resourceAssignmentExpression> <bpmn:formalExpression>activitiTeam</bpmn:formalExpression> </bpmn:resourceAssignmentExpression> </bpmn:potentialOwner> </bpmn:userTask>
屬於該組的用戶將能夠領取任務並處理任務。