Activiti 是一个自动化工作流框架。它能帮助企业快速搭建分布式、高扩展的工作流框架。

下面这篇文章将会带你探索Activiti 工作流核心运行时API - TaskRuntime API。(P.S. 这篇文章基本上是我对官网文章的翻译,英文好的请看官网原文

TaskRuntime API

下面有写一些demo.这些demo是Activiti官网展示的一些例子,你可以从这个地址下载这些demo。

TaskRunTime API 部分的例子可以在activiti-api-basic-task-example模块中找到。


pom.xml

在Spring Boot2 中使用Activiti添加相关依赖以及数据库驱动就行。

比如在pom.xml文件中添加以下依赖:pom.xml

<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>

建议使用下面的BOM

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-dependencies</artifactId>
<version>7.1.0.M4</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>

注册TaskRuntime实例

通过下面的方式我们可以将TaskRuntime的实例注册到APP中。

@Autowired
private TaskRuntime taskRuntime;

TaskRuntime接口中定义了一系列方法来帮助我们创建任务实例以及与任务进行交互,源码如下所示。

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);
...
}

我们可以使用TaskPayloadBuilder参数化任务的信息,来平滑地构建一个TaskRuntime实例:

taskRuntime.create(
TaskPayloadBuilder.create()
.withName("First Team Task")
.withDescription("This is something really important")
.withGroup("activitiTeam")
.withPriority(10)
.build());

上面方式创建的任务只能被 “activitiTeam” 这个分组以及任务拥有者(当前登录用户)看到。


角色与分组

在SpringBoot 工程中,为了安全考虑,角色和分组的创建Activiti依赖Spring Security 模块。在SpringBoot 工程中我们可以使用 UserDetailsService来配置可以与任务进行交互的用户以及他们各自对应的角色和分组。这个demo中是在@Configuration 配置的类中进行设置的.

需要注意的是:与TaskRuntime API 交互,必须拥有 ACTIVITI_USER 角色 (权限是: ROLE_ACTIVITI_USER)。

当与REST端点进行交互的时候,Activiti授权机构将自动设置当前登录用户。但是因为这个demo是一个教学性质的实例,它允许我们手动设置当前登录用户。在实际的工作场景中,千万不要这么做,除非你想不经过REST端点(例如HTTP请求)就改变登录用户。


任务事件监听器

最后一件需要强调的事情就是任务事件监听器的注册。

我们可以按照需要注册任意多个TaskRuntimeEventListeners。当服务触发运行时事件时,监听器能够监听到这一动作,并通知应用程序。

@Bean
public TaskRuntimeEventListener taskAssignedListener() {
return taskAssigned
-> logger.info(
">>> Task Assigned: '"
+ taskAssigned.getEntity().getName()
+"' We can send a notification to the assignee: "
+ taskAssigned.getEntity().getAssignee());
}



### DemoApplication 源码
下面是DemoApplication的源码,注释里已经详细地解释了代码的含义。完整代码请查看[官方源码](https://github.com/Activiti/activiti-examples/tree/master/activiti-api-basic-task-example):
```java
package org.activiti.examples;

import org.activiti.api.runtime.shared.query.Page;

import org.activiti.api.runtime.shared.query.Pageable;

import org.activiti.api.task.model.Task;

import org.activiti.api.task.model.builders.TaskPayloadBuilder;

import org.activiti.api.task.runtime.TaskRuntime;

import org.activiti.api.task.runtime.events.TaskAssignedEvent;

import org.activiti.api.task.runtime.events.TaskCompletedEvent;

import org.activiti.api.task.runtime.events.listener.TaskRuntimeEventListener;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.boot.CommandLineRunner;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.context.annotation.Bean;

@SpringBootApplication

public class DemoApplication implements CommandLineRunner {

private Logger logger = LoggerFactory.getLogger(DemoApplication.class);

@Autowired
private TaskRuntime taskRuntime;
@Autowired
private SecurityUtil securityUtil; public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args); } @Override
public void run(String... args) { // Using Security Util to simulate a logged in user
securityUtil.logInAs("salaboy"); // Let's create a Group Task (not assigned, all the members of the group can claim it)
// Here 'salaboy' is the owner of the created task
logger.info("> Creating a Group Task for 'activitiTeam'");
taskRuntime.create(TaskPayloadBuilder.create()
.withName("First Team Task")
.withDescription("This is something really important")
.withCandidateGroup("activitiTeam")
.withPriority(10)
.build()); // Let's log in as 'other' user that doesn't belong to the 'activitiTeam' group
securityUtil.logInAs("other"); // Let's get all my tasks (as 'other' user)
logger.info("> Getting all the tasks");
Page<Task> tasks = taskRuntime.tasks(Pageable.of(0, 10)); // No tasks are returned
logger.info("> Other cannot see the task: " + tasks.getTotalItems()); // Now let's switch to a user that belongs to the activitiTeam
securityUtil.logInAs("erdemedeiros"); // Let's get 'erdemedeiros' tasks
logger.info("> Getting all the tasks");
tasks = taskRuntime.tasks(Pageable.of(0, 10)); // 'erdemedeiros' can see and claim the task
logger.info("> erdemedeiros can see the task: " + tasks.getTotalItems()); String availableTaskId = tasks.getContent().get(0).getId(); // Let's claim the task, after the claim, nobody else can see the task and 'erdemedeiros' becomes the assignee
logger.info("> Claiming the task");
taskRuntime.claim(TaskPayloadBuilder.claim().withTaskId(availableTaskId).build()); // Let's complete the task
logger.info("> Completing the task");
taskRuntime.complete(TaskPayloadBuilder.complete().withTaskId(availableTaskId).build());
} @Bean
public TaskRuntimeEventListener<TaskAssignedEvent> taskAssignedListener() {
return taskAssigned -> logger.info(">>> Task Assigned: '"
+ taskAssigned.getEntity().getName() +
"' We can send a notification to the assginee: " + taskAssigned.getEntity().getAssignee());
}
@Bean
public TaskRuntimeEventListener<TaskCompletedEvent> taskCompletedListener() {
return taskCompleted -> logger.info(">>> Task Completed: '"
+ taskCompleted.getEntity().getName() +
"' We can send a notification to the owner: " + taskCompleted.getEntity().getOwner());
}

}

下面是运行结果
> ...
2019-10-05 16:58:53.900 INFO 6268 --- [ main] o.a.e.DemoApplicationConfiguration : > Registering new user: salaboy with the following Authorities[[ROLE_ACTIVITI_USER, GROUP_activitiTeam]]
2019-10-05 16:58:54.175 INFO 6268 --- [ main] o.a.e.DemoApplicationConfiguration : > Registering new user: ryandawsonuk with the following Authorities[[ROLE_ACTIVITI_USER, GROUP_activitiTeam]]
2019-10-05 16:58:54.422 INFO 6268 --- [ main] o.a.e.DemoApplicationConfiguration : > Registering new user: erdemedeiros with the following Authorities[[ROLE_ACTIVITI_USER, GROUP_activitiTeam]]
2019-10-05 16:58:54.580 INFO 6268 --- [ main] o.a.e.DemoApplicationConfiguration : > Registering new user: other with the following Authorities[[ROLE_ACTIVITI_USER, GROUP_otherTeam]]
2019-10-05 16:58:54.742 INFO 6268 --- [ main] o.a.e.DemoApplicationConfiguration : > Registering new user: admin with the following Authorities[[ROLE_ACTIVITI_ADMIN]]
...
2019-10-05 16:59:00.232 INFO 6268 --- [ main] org.activiti.examples.SecurityUtil : > Logged in as: salaboy
2019-10-05 16:59:00.233 INFO 6268 --- [ main] org.activiti.examples.DemoApplication : > Creating a Group Task for 'activitiTeam'
2019-10-05 16:59:00.261 INFO 6268 --- [ main] org.activiti.examples.SecurityUtil : > Logged in as: other
2019-10-05 16:59:00.261 INFO 6268 --- [ main] org.activiti.examples.DemoApplication : > Getting all the tasks
2019-10-05 16:59:00.380 INFO 6268 --- [ main] org.activiti.examples.DemoApplication : > Other cannot see the task: 0
2019-10-05 16:59:00.380 INFO 6268 --- [ main] org.activiti.examples.SecurityUtil : > Logged in as: erdemedeiros
2019-10-05 16:59:00.380 INFO 6268 --- [ main] org.activiti.examples.DemoApplication : > Getting all the tasks
2019-10-05 16:59:00.395 INFO 6268 --- [ main] org.activiti.examples.DemoApplication : > erdemedeiros can see the task: 1
2019-10-05 16:59:00.395 INFO 6268 --- [ main] org.activiti.examples.DemoApplication : > Claiming the task
2019-10-05 16:59:00.405 INFO 6268 --- [ main] org.activiti.examples.DemoApplication : >>> Task Assigned: 'First Team Task' We can send a notification to the assginee: erdemedeiros
2019-10-05 16:59:00.425 INFO 6268 --- [ main] org.activiti.examples.DemoApplication : > Completing the task
2019-10-05 16:59:00.457 INFO 6268 --- [ main] org.activiti.examples.DemoApplication : >>> Task Completed: 'First Team Task' We can send a notification to the owner: salaboy

Activiti(1) - TaskRuntime API 入门的更多相关文章

  1. Web API 入门指南 - 闲话安全

    Web API入门指南有些朋友回复问了些安全方面的问题,安全方面可以写的东西实在太多了,这里尽量围绕着Web API的安全性来展开,介绍一些安全的基本概念,常见安全隐患.相关的防御技巧以及Web AP ...

  2. 转载-Web API 入门

    An Introduction to ASP.NET Web API 目前感觉最好的Web API入门教程 HTTP状态码 Web API 强势入门指南 Install Mongodb Getting ...

  3. Hadoop MapReduce编程 API入门系列之压缩和计数器(三十)

    不多说,直接上代码. Hadoop MapReduce编程 API入门系列之小文件合并(二十九) 生成的结果,作为输入源. 代码 package zhouls.bigdata.myMapReduce. ...

  4. Web API入门指南(安全)转

    安全检测的工具站点:https://www.owasp.org/index.php/Category:Vulnerability_Scanning_Tools Web API入门指南有些朋友回复问了些 ...

  5. 【ASP.NET Web API教程】1 ASP.NET Web API入门

    原文 [ASP.NET Web API教程]1 ASP.NET Web API入门 Getting Started with ASP.NET Web API第1章 ASP.NET Web API入门 ...

  6. Web API 入门指南

    Web API 入门指南 - 闲话安全2013-09-21 18:56 by 微软互联网开发支持, 231 阅读, 3 评论, 收藏, 编辑 Web API入门指南有些朋友回复问了些安全方面的问题,安 ...

  7. 使用Jax-rs 开发RESTfull API 入门

    使用Jax-rs 开发RESTfull API 入门 本文使用 Jersey 2开发RESTfull API.Jersey 2 是 JAX-RS 接口的参考实现 使用到的工具 Eclipse Neon ...

  8. Web API 入门 二 媒体类型

    还是拿上面 那篇 Web API 入门 一  的那个来讲 在product类中加一个时间属性

  9. HBase编程 API入门系列之create(管理端而言)(8)

    大家,若是看过我前期的这篇博客的话,则 HBase编程 API入门系列之put(客户端而言)(1) 就知道,在这篇博文里,我是在HBase Shell里创建HBase表的. 这里,我带领大家,学习更高 ...

随机推荐

  1. 牛客小白月赛6 J 洋灰三角 数学

    链接:https://www.nowcoder.com/acm/contest/136/J来源:牛客网 题目描述     洋灰是一种建筑材料,常用来筑桥搭建高层建筑,又称,水泥.混凝土.     WH ...

  2. 2019 HZNU Winter Training Day 15 Comprehensive Training

    A - True Liars 题意: 那么如果一个人说另一个人是好人,那么如果这个人是好人,说明 对方确实是好人,如果这个是坏人,说明这句话是假的,对方也是坏人. 如果一个人说另一个人是坏人,那么如果 ...

  3. Codeforces Round #479 (Div. 3) B. Two-gram

    原题代码:http://codeforces.com/contest/977/problem/B 题解:有n个字符组成的字符串,输出出现次数两个字符组合.例如第二组样例ZZ出现了两次. 方法:比较无脑 ...

  4. c++11特性学习总结

    ubuntu 16.04 自带gcc 5.4 支持c++11 ubuntu 18.04 自带gcc 7.3 支持c++14 查看编译器支持: c++11 c++14 c++17 c++11 featu ...

  5. 【Offer】[56-2] 【数组中唯一只出现一次的数字】

    题目描述 思路分析 测试用例 Java代码 代码链接 题目描述 在一个数组中除一个数字只出现一次之外,其他数字都出现了三次.请找出那个只出现一次的数字 [牛客网刷题地址]无 思路分析 如果一个数字出现 ...

  6. debug 模式缓慢

    debug 模式启动服务器,然后在 breakopints下可以看到打的断点.清除全部重启服务器,问题解决.

  7. 湘潭大学oj循环1-5

    #include <stdio.h>#include <stdlib.h> int main(){   int b,s,n;    int a[101]; A:scanf(&q ...

  8. 小程序组件 scroll-view 横向滚动条无效

    小程序组件 scroll-view 中分别有上下竖向滑动和左右横向滑动,在这次项目中刚好需要用到横向滑动,但在测试过程中发现横向滑动没有了效果(静止在那里没移动过,并且换行了),经调试发现: 1.sc ...

  9. JAVA截取后String字符串六位字符

    public static void main(String[] args){ String cellphone="; String pwd = cellphone.substring(ce ...

  10. @classmethod @staticmethod 个人理解

    官方解释 @classmethod 一个类方法把类自己作为第一个实参, 就像一个实例方法把实例自己作为第一个实参. 语法格式: class C: @classmethod def f(cls, arg ...