简介
Activiti是领先的轻量级的,以Java为中心的开源BPMN(Business Process Modeling Notation)引擎,实现了真正的流程自动化。下面介绍如何在SpringBoot环境下使用Maven集成Activiti6,来实现一个简单的流程开发。
添加依赖(Springboot:2.2.1)
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter-basic</artifactId>
<version>6.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
流程文件加创建或设置
SpringBoot集成activiti默认会从classpath下(如工程目录的resource目录)的processes目录下读取流程定义文件,所以需要在src/main/resources目录下添加processes目录,并在目录中创建流程文件。
tips:1、如果目录是其他位置,可在配置文件配置,配置项为:spring.activiti.process-definition-location-prefix;
2、Spring集成Activiti6默认支持 **.bpmn20.xml 和 **.bpmn 格式的流程定义文件,修改支持的文件格式,通过配置spring.activiti.process-definition-location-suffixes修改。
配置文件例如下:
#activiti配置
#是否自动检查、部署流程定义文件
spring.activiti.check-process-definitions=true
#自动更新数据库结构(默认是),生产环境时设置为false,减少启动时间。
spring.activiti.database-schema-update=true
#流程文件前缀和后缀(保存路径和文件名)
spring.activiti.process-definition-location-prefix=classpath:/processes/
spring.activiti.process-definition-location-suffixes=.bpmn20.xml,.bpmn
配置数据源
配置文件中配置一个数据源供使用。
注意,请配置全,不能跟单独的Springboot项目一样省略driver-class 和initial-size,而且url必须配置全,比如时区,否则启动会报错。
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/activiti?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=utf8&autoReconnect=true&useSSL=false&allowMultiQueries=true
spring.datasource.username=unm
spring.datasource.password=pwd
spring.datasource.tomcat.initial-size=4
创建一个流程
在processes文件夹下新建一个demo.bpmn文件,并编写一个简单的请假流程。
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" xmlns:tns="http://www.activiti.org/test" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" expressionLanguage="http://www.w3.org/1999/XPath" id="m1578292452475" name="" targetNamespace="http://www.activiti.org/test" typeLanguage="http://www.w3.org/2001/XMLSchema">
<process id="demoProcess" name="请假流程" isClosed="false" isExecutable="true" processType="None">
<startEvent id="start" name="startEvent"/>
<sequenceFlow id="__4" sourceRef="start" targetRef="_1"/>
<userTask activiti:exclusive="true" id="_1" name="领导审批" activiti:assignee="leader"/>
<sequenceFlow id="__5" sourceRef="_1" targetRef="end"/>
<endEvent id="end"/>
</process>
</definitions>
启动测试
启动application时会报错:
java.lang.IllegalArgumentException: Could not find class [org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration]
解决方法:启动时排除这个类,修改注解:
@SpringBootApplication
改为
@SpringBootApplication(exclude = SecurityAutoConfiguration.class)
再次启动,已启动成功,检查数据库,表已建立。
编写接口
1、Task描述类 TaskRepresentation
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TaskRepresentation {
private String id;
private String name;
}
2、控制器类 ProcessController
@RestController
@RequestMapping("/process")
public class ProcessController {
@Autowired
private RuntimeService runtimeService;
@Autowired
private TaskService taskService;
/**
* 发起一个请假流程。
* @return 请假流程的id。
*/
@GetMapping("/start")
public ResponseEntity<String> startProcess(){
//创建一个流程,参数key是bpmn文件内定义的流程的id。
ProcessInstance pro = runtimeService.startProcessInstanceByKey("demoProcess");
return ResponseEntity.ok(pro.getId());
}
/**
* 获取待办任务列表
* @param uid 用户id
* @return
*/
@GetMapping("/task/{uid}")
public ResponseEntity<List<TaskRepresentation>> getTask(@PathVariable String uid) {
List<Task> tasks = taskService.createTaskQuery().taskAssignee(uid).list();
return ResponseEntity.ok(CommonUtil.transformTask(tasks));
}
/**
* 审批通过
* @param taskId
* @return
*/
@GetMapping("/task/apply/{taskId}")
public ResponseEntity<String> apply(@PathVariable String taskId){
taskService.complete(taskId);
return ResponseEntity.ok("领导同意");
}
}
3、Task转TaskRepresentation方法
public class CommonUtil {
public static TaskRepresentation transformTask(Task task) {
return new TaskRepresentation(task.getId(),task.getName());
}
public static List<TaskRepresentation> transformTask(List<Task> tasks){
if (tasks != null) {
final List<TaskRepresentation> list = new ArrayList<>();
tasks.forEach(task -> {
list.add(new TaskRepresentation(task.getId(),task.getName()));
});
return list;
}else {
return null;
}
}
}
接口测试
1、创建流程(注意,返回的是实例id)
2、查找待办流程(注意,这里的id是taskid,可以查看act_ru_task表)
http://localhost:8080/process/task/leader
[{“id”:“5005”,“name”:“领导审批”}]
3、审批同意(同意之后再调用上一步的接口时会发现,已无待办流程)
附:整个项目目录结构