# SpringBoot+Activiti
**Repository Path**: tyutliugang/spring-boot-activiti
## Basic Information
- **Project Name**: SpringBoot+Activiti
- **Description**: springboot集成activiti实现流程的创建,审批,查询,历史记录等功能
- **Primary Language**: Java
- **License**: GPL-3.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 9
- **Created**: 2025-07-27
- **Last Updated**: 2025-07-27
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
## 啦啦啦啦啦,富贵同学又开始开坑了,出了个免费的专栏,主要给大家从0基础开始用springBoot集成第三方的插件或者功能,如果这篇专栏能帮到你,一定不要忘了点一个赞哦!!欢迎大家收藏分享

## 第一步,导入jar包
```java
org.activiti
activiti-spring-boot-starter-basic
5.22.0
```
这是activiti的核心包,我们还添加其他的jar包
```java
org.springframework.boot
spring-boot-starter
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-starter-web
mysql
mysql-connector-java
5.1.30
```
## 第二步,编写配置文件
```java
server:
port: 8089
spring:
datasource:
url: jdbc:mysql://localhost:3306/activiti
driver-class-name: com.mysql.jdbc.Driver
username: root
password: 123456
```
## 第三步,创建activiti库

## 第四步,运行启动类

好,遇到这个时候就出现问题了,这是富贵同学替大家踩坑了,大家记得避开
**启动报错Could not find class [org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration]**
这个问题是activiti里面本身会依赖Security,所以我们将他排除,我们在启动类上加上
```java
exclude = SecurityAutoConfiguration.class
```

好的,我们启动,这个时候又碰见另外的一个问题
**Caused by: java.io.FileNotFoundException: class path resource [processes/] cannot be resolved to URL because it does not exist**
这个是因为activiti在启动的时候会去找bpm文件,会去到默认的processes文件夹中找,
这个时候我们在配置类中加入
```java
activiti:
check-process-definitions: false
```

这个时候就启动成功啦!

## 第五步.启动成功之后查看我们的数据库

就会发现25张表已经自动生成了!
如果没有看过富贵同学的第一篇请移步到这个地址查看[SpringBoot集成Activiti(一)](https://blog.csdn.net/csdnerM/article/details/121680351)
第一步,取消yml的配置,因为我们需要创建一个流程

`leave.bpmn`文件感谢(https://gitee.com/shenzhanwang/Spring-activiti)提供的流程文件
```java
```
这是一个简单的请假申请流程
## 第六步,放入指定的文件夹中之后,我们重新启动启动类
## 第七步,查看我们的数据表
`ACT_RE_PROCDEF`中可以查看到我们的流程

至此之后我们的流程就创建完成了,现在来我们的api操作
## 第八步,由于我们要跟我们的业务连接到一起,所以我们创建一个请假表
```java
CREATE TABLE `leave` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`process_instance_id` varchar(45) DEFAULT NULL COMMENT '流程表id',
`user_id` varchar(20) DEFAULT NULL COMMENT '用户id',
`start_time` varchar(45) DEFAULT NULL COMMENT '开始时间',
`end_time` varchar(45) DEFAULT NULL COMMENT '结束时间',
`leave_type` varchar(45) DEFAULT NULL COMMENT '请假类型',
`reason` varchar(400) DEFAULT NULL COMMENT '请假原因',
`apply_time` datetime DEFAULT NULL COMMENT '通过时间',
`reality_start_time` varchar(45) DEFAULT NULL COMMENT '请假开始时间',
`reality_end_time` varchar(45) DEFAULT NULL COMMENT '请假结束时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='请假表';
```

## 第九步,集成底层框架
对了,我们没有数据库框架,这里我们使用[mybatisPlusPro](https://blog.csdn.net/csdnerM/article/details/121565202)来作为底层框架
## 第十步,创建controller等类
```java
import com.wangfugui.activiti.dao.LeaveDO;
import com.wangfugui.activiti.service.LeaveService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author MaSiyi
* @version 1.0.0 2021/12/2
* @since JDK 1.8.0
*/
@RestController
@RequestMapping("/leave")
public class LeaveController extends BaseController{
}
```
```java
import com.baomidou.mybatisplus.extension.service.IService;
import com.wangfugui.activiti.dao.LeaveDO;
/**
* @author MaSiyi
* @version 1.0.0 2021/12/2
* @since JDK 1.8.0
*/
public interface LeaveService extends IService {
}
```
```java
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wangfugui.activiti.dao.LeaveDO;
import com.wangfugui.activiti.dao.mapper.LeaveMapper;
import com.wangfugui.activiti.service.LeaveService;
import org.springframework.stereotype.Service;
/**
* @author MaSiyi
* @version 1.0.0 2021/12/2
* @since JDK 1.8.0
*/
@Service
public class LeaveServiceImpl extends ServiceImpl implements LeaveService {
}
```java
hellow啊,靓仔,有没有看过前面的内容啊?
请移步到前面的内容去看(一)(二)的内容
接下来我们开始和我们的业务结合到一起。
```
还是先回顾一下上期内容,上期有个遗留的问题,就是mabatis jar包会冲突,所以我们
```java
org.activiti
activiti-spring-boot-starter-basic
5.22.0
org.mybatis
mybatis
```
## 第十一步,好的,为了接下来方便接口的测试,我们使用swagger来快速搭建
```java
io.springfox
springfox-swagger2
2.7.0
io.springfox
springfox-swagger-ui
2.7.0
```
## 第十二步,编写controller类
```java
import com.wangfugui.activiti.dao.LeaveVo;
import com.wangfugui.activiti.dao.Leaves;
import com.wangfugui.activiti.dao.dto.HandleDto;
import com.wangfugui.activiti.dao.dto.UpcomingDto;
import com.wangfugui.activiti.service.LeaveService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* @author MaSiyi
* @version 1.0.0 2021/12/2
* @since JDK 1.8.0
*/
@RestController
@RequestMapping("/leave")
@Api(tags = "请假")
public class LeaveController {
@Autowired
protected LeaveService leaveService;
@PostMapping("/startLeave")
@ApiOperation("发起一个请假流程")
public String startLeave(@RequestBody Leaves leave) {
return leaveService.startLeave(leave);
}
@PostMapping("/upcoming")
@ApiOperation("获取待办列表")
public List listTask(@RequestBody UpcomingDto upcomingDto) {
return leaveService.upcoming(upcomingDto);
}
@PostMapping("/handle")
@ApiOperation("处理流程")
public String handle(@RequestBody HandleDto handleDto) {
return leaveService.handle(handleDto);
}
}
```
这次我们先来个简单的创建流程,获取待办流程,审批流程
所以我们就看到了这三个接口
## 第十三步,我们进入到实现类中查看
```java
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wangfugui.activiti.dao.LeaveVo;
import com.wangfugui.activiti.dao.Leaves;
import com.wangfugui.activiti.dao.dto.HandleDto;
import com.wangfugui.activiti.dao.dto.UpcomingDto;
import com.wangfugui.activiti.dao.mapper.LeaveMapper;
import com.wangfugui.activiti.service.LeaveService;
import org.activiti.engine.IdentityService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
/**
* @author MaSiyi
* @version 1.0.0 2021/12/2
* @since JDK 1.8.0
*/
@Service
public class LeaveServiceImpl extends ServiceImpl implements LeaveService {
@Autowired
private RuntimeService runtimeservice;
@Autowired
private IdentityService identityservice;
@Autowired
private TaskService taskservice;
/**
* 开启一个流程
*
* @param leave
* @Param: [leave]
* @return: org.activiti.engine.runtime.ProcessInstance
* @Author: MaSiyi
* @Date: 2021/12/3
*/
@Override
public String startLeave(Leaves leave) {
leave.setId(UUID.randomUUID().toString().substring(0, 8));
//设置用户
identityservice.setAuthenticatedUserId(leave.getUserId());
//使用leaveapply表的主键作为businesskey,连接业务数据和流程数据
String businesskey = String.valueOf(leave.getId());
//发起请假流程
Map map = new HashMap<>();
//下个步骤处理人
map.put("deptleader", "Tom");
ProcessInstance processInstance = runtimeservice.startProcessInstanceByKey("leave", businesskey, map);
String instanceid = processInstance.getId();
//关联流程表
leave.setProcessInstanceId(instanceid);
this.save(leave);
return "申请成功";
}
/**
* 获取待办列表
*
* @param upcomingDto
* @Param: [upcomingDto]
* @return: java.util.List
* @Author: MaSiyi
* @Date: 2021/12/3
*/
@Override
public List upcoming(UpcomingDto upcomingDto) {
List leaves = new ArrayList<>();
// 使用任务候选人查询待办列表
List tasks = taskservice.createTaskQuery().taskAssignee(upcomingDto.getUsername()).taskName("部门领导审批")
.listPage(upcomingDto.getPage(), upcomingDto.getSize());
for (Task task : tasks) {
String instanceId = task.getProcessInstanceId();
//查询正在运行的task
ProcessInstance processInstance = runtimeservice.createProcessInstanceQuery().processInstanceId(instanceId).singleResult();
String businessKey = processInstance.getBusinessKey();
Leaves leave = this.getById(businessKey);
LeaveVo leaveVo = new LeaveVo();
BeanUtils.copyProperties(leave,leaveVo);
leaveVo.setTaskId(task.getId());
leaves.add(leaveVo);
}
return leaves;
}
/**
* 审批任务
* @Param: [taskid]
* @return: java.lang.String
* @Author: MaSiyi
* @Date: 2021/12/3
*/
@Override
public String handle(HandleDto handleDto) {
//完成指定任务
taskservice.claim(handleDto.getTaskId(), handleDto.getUserName());
//进行下一个任务
Map variables = new HashMap();
variables.put("deptleaderapprove", handleDto.getApprove());
variables.put("hr", handleDto.getNextUserNam());
taskservice.complete(handleDto.getTaskId(), variables);
return "处理成功";
}
}
```
这三个的解释已经写在代码里面啦,大家可以去看看注释
## 第十四步,我们来看一下我们的测试
发起一个流程


查询我们的待办


处理我们的待办


好了,今天的简单的基本方法就到这里了
下一篇介绍查看历史流程等的集成
今天我们来讲一下历史流程
## 第十五步首先我们要知道activiti中历史Service是`HistoryService`
所以我们第一步就将`HistoryService`注入进来

## 第十六步,编写获取历史流程方法
```java
@GetMapping("/myleave")
@ApiOperation("我发起的请假流程")
public List myleave(@RequestParam String userId) {
return leaveService.myleave(userId);
}
```
这个接口是根据userId获取发起的请假流程
```java
@GetMapping("/getHistory")
@ApiOperation("获取历史流程信息")
public HistoricProcessInstance getHistory(@RequestParam String procInstId) {
return leaveService.getHiProcByProcInstId(procInstId);
}
```
这个接口是什么呢 `procInstId`又是什么?


第三个接口
```java
@GetMapping("/getHiProcByProcKeyAndBusinessID")
@ApiOperation("获取历史任务")
public HistoricProcessInstance getHiProcByProcKeyAndBusinessID(@RequestParam String procKey, @RequestParam String businessID) {
return leaveService.getHiProcByProcKeyAndBusinessID(procKey, businessID);
}
```
procKey和businessID又是什么?

businessID是我们的业务主键

关联在这张表中

