新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>
属于该组的用户将能够领取任务并处理任务。