说明
本系列教程目前已经完结,点击以下链接查看完整教程
- SpringBoot Activiti6系列教程(一)-activiti-app部署
- SpringBoot Activiti6系列教程(二)-基于mysql数据库初始化
- SpringBoot Activiti6系列教程(三)-开发一个简单的SpringBoot activiti6应用程序
- SpringBoot Activiti6系列教程(四)-流程部署
- SpringBoot Activiti6系列教程(五)-activiti api
- SpringBoot Activiti6系列教程(六)-Execution说明
- SpringBoot Activiti6系列教程(七)-变量
- SpringBoot Activiti6系列教程(八)-流程拒绝实现
- SpringBoot Activiti6系列教程(九)-流程回退实现
- SpringBoot Activiti6系列教程(十)-流程加签征询实现(完结篇)
BPMN建模
在前面两节,我们介绍了如何部署activiti三个应用以及如何使用第三方数据库,如果你还没阅读前两章也不影响本文的阅读,如果有兴趣了解下,可以点击以下链接
从本章开始,就正式开始activiti程序开发,我们先从一个最简单的activiti流程开发,流程图如下:
流程很简单,发起后,由管理员admin
审批,然后结束。
bpmn源文件代码如下
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" 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" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/processdef">
<process id="SimpleProcess" name="SimpleProcess" isExecutable="true">
<startEvent id="startEvent1"></startEvent>
<userTask id="sid-2B2AA039-82D2-479C-8FE9-6F48E4478BD8" name="Admin Approver" activiti:assignee="admin">
<extensionElements>
<modeler:activiti-idm-assignee xmlns:modeler="http://activiti.com/modeler"><![CDATA[true]]></modeler:activiti-idm-assignee>
<modeler:assignee-info-email xmlns:modeler="http://activiti.com/modeler"><![CDATA[admin]]></modeler:assignee-info-email>
<modeler:assignee-info-lastname xmlns:modeler="http://activiti.com/modeler"><![CDATA[Administrator]]></modeler:assignee-info-lastname>
<modeler:initiator-can-complete xmlns:modeler="http://activiti.com/modeler"><![CDATA[false]]></modeler:initiator-can-complete>
</extensionElements>
</userTask>
<sequenceFlow id="sid-F506EEC7-0411-4A97-930D-87500FF1414F" sourceRef="startEvent1" targetRef="sid-2B2AA039-82D2-479C-8FE9-6F48E4478BD8"></sequenceFlow>
<endEvent id="sid-2C31753A-3AE2-4C91-B4F8-3B5EED2B4FC5"></endEvent>
<sequenceFlow id="sid-9FC989EE-BBC3-4EB2-A7AF-DA4F2649A68F" sourceRef="sid-2B2AA039-82D2-479C-8FE9-6F48E4478BD8" targetRef="sid-2C31753A-3AE2-4C91-B4F8-3B5EED2B4FC5"></sequenceFlow>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_SimpleProcess">
<bpmndi:BPMNPlane bpmnElement="SimpleProcess" id="BPMNPlane_SimpleProcess">
<bpmndi:BPMNShape bpmnElement="startEvent1" id="BPMNShape_startEvent1">
<omgdc:Bounds height="30.0" width="30.0" x="100.0" y="163.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="sid-2B2AA039-82D2-479C-8FE9-6F48E4478BD8" id="BPMNShape_sid-2B2AA039-82D2-479C-8FE9-6F48E4478BD8">
<omgdc:Bounds height="80.0" width="100.0" x="255.0" y="138.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="sid-2C31753A-3AE2-4C91-B4F8-3B5EED2B4FC5" id="BPMNShape_sid-2C31753A-3AE2-4C91-B4F8-3B5EED2B4FC5">
<omgdc:Bounds height="28.0" width="28.0" x="465.0" y="164.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="sid-F506EEC7-0411-4A97-930D-87500FF1414F" id="BPMNEdge_sid-F506EEC7-0411-4A97-930D-87500FF1414F">
<omgdi:waypoint x="130.0" y="178.0"></omgdi:waypoint>
<omgdi:waypoint x="255.0" y="178.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="sid-9FC989EE-BBC3-4EB2-A7AF-DA4F2649A68F" id="BPMNEdge_sid-9FC989EE-BBC3-4EB2-A7AF-DA4F2649A68F">
<omgdi:waypoint x="355.0" y="178.0"></omgdi:waypoint>
<omgdi:waypoint x="465.0" y="178.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
你可以使用任何一个支持BPMN2.0的工具进行流程的建模,如果你是用eclipse开发,activiti在eclipse下有一个非常好用的插件,并且activit也提供一个web版的建模工具,就在activiti-app这个应用下,关于如何部署该应用,你可以查看之前的文章SpringBoot Activiti6系列教程(一)-activiti-app部署。以上模型就是通过activiti-app创建导出的。
SpringBoot 开发
SpringBoot 介绍
Spring Boot是一个应用开发框架,基于spring,相比spring开发,spring boot极大简化了配置,并且遵守约定优于配置的原则即使0配置也能正常运行,这在spring中是难以想象的。spring boot应用程序可以独立运行,框架内嵌web容器,使得web应用程序可以像本地程序一样启动和调试,十分的方便,这种设计方式也使得spring boot应用程序非常适合容器化进行大规模部署,而且spring boot提供了非常丰富的组件,流行的java web框架基本都有spring boot版本,生态十分庞大,是目前java web开发最好的方案。
创建spring boot的工程
如果你已经对spring boot非常熟悉,可以跳过该章节。
本次教程代码都是通过IntelliJ IDEA
进行开发,基于Spring Boot 2.1.2
版本,如果你还没用过IntelliJ IDEA,建议你尝试下。
-
1.
创建一个maven
工程 -
2.
设置项目parent并且加入spring boot的依赖和activiti相关依赖,参考pom.xml如下
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.definesys.tutorial.activiti</groupId>
<artifactId>activiti-tutorial</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>activiti-tutorial1</module>
</modules>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.2.RELEASE</version>
<relativePath/>
</parent>
<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>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>1.4.185</version>
</dependency>
</dependencies>
</project>
spring-boot-starter-web
是spring boot用来创建rest服务的组件,h2是一个内存数据库,如果你没有配置数据库,那么加入h2后,无需配置第三方数据库即可运行activit应用。
-
3.
在resource
文件夹下创建文件夹processes
(文件夹名字不能修改),并且将第一步创建的模型文件拷贝至该文件下。 -
4.
创建两个接口,/acitiviti/start
可以发起该流程,/activiti/task?uid=admin
可以查询admin的流程待办,依次创建appliaction,dto,service,controller相关代码文件,如下
本文所有代码已上传至github,仓库地址为 https://github.com/wls1036/springboot-activiti6-tutorial 欢迎star
ActivititiApplication.java
@SpringBootApplication(exclude = SecurityAutoConfiguration.class)
public class ActivititiApplication {
public static void main(String[] args) {
SpringApplication.run(ActivititiApplication.class);
}
}
之所以要加exclude = SecurityAutoConfiguration.class
,原因是不加的话启动会报Caused by: java.lang.ArrayStoreException: sun.reflect.annotation.TypeNotPresentExceptionProxy
错误,可能是spring boot的版本原因引起的。
TaskRepresentation.java
public class TaskRepresentation {
private String id;
private String name;
public TaskRepresentation(String id, String name) {
this.id = id;
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
ActivitiService.java
@Service
public class ActivitiService {
@Autowired
private RuntimeService runtimeService;
@Autowired
private TaskService taskService;
/**
* start activiti process
*
* @return instance id
*/
public String start() {
ProcessInstance instance = runtimeService.startProcessInstanceByKey("SimpleProcess");
return instance.getId();
}
/**
* get user task list
*
* @param uid
* @return user task list
*/
public List<Task> getTask(String uid) {
List<Task> tasks = taskService.createTaskQuery().taskAssignee(uid).list();
return tasks;
}
}
RuntimeService
包含了activiti运行时接口,可以通过点击进入查看源文件,acitivi api设计的相当友好,很多接口看名称就差不多知道功能,startProcessInstanceByKey是根据流程编号发起流程,参数为bpmn文件中 process id="SimpleProcess"
中的id字段。
TaskService
包含任务相关api,createTaskQuery可以创建一个任务查询,activiti的api使用方法基本都一样,比如查询类的,都是createXXXQuery创建一个查询类后执行查询条件,list()是返回一个list数组。这里是指定审批人,在bpmn文件中,我们指定了审批人为admin
<userTask id="sid-2B2AA039-82D2-479C-8FE9-6F48E4478BD8" name="Admin Approver" activiti:assignee="admin">
ActivitiController
@RestController
@RequestMapping(value = "activiti")
public class ActivitiController {
@Autowired
private ActivitiService service;
@RequestMapping(value = "start", method = RequestMethod.GET)
public String start() {
return service.start();
}
@RequestMapping(value = "task", method = RequestMethod.GET)
public List<TaskRepresentation> getTask(@RequestParam(value = "uid") String uid) {
List<Task> tasks = service.getTask(uid);
List<TaskRepresentation> dtos = new ArrayList<>();
for (Task task : tasks) {
dtos.add(new TaskRepresentation(task.getId(), task.getName()));
}
return dtos;
}
}
应用测试
- 流程发起测试
curl http://localhost:8080/activiti/start
65
- 获取待办测试
curl http://localhost:8080/activiti/task?uid=admin
[{"id":"65","name":"Admin Approver"}]
更改数据源
现在的数据都保存到内存数据库h2中,程序重新启动就会丢失,这显然不是我们想要的结果,我们需要将数据保存到外部数据库,关于如何初始化外部数据库,可以参考之前的文章SpringBoot Activiti6系列教程(二)-基于mysql数据库初始化,这里不在赘述。假设你已经初始化完数据库。
- 新建一个数据源配置类
@Configuration
public class ActivitiConfiguration {
@Bean
public DataSource database() {
return DataSourceBuilder.create()
.url("jdbc:mysql://localhost:3306/activiti?useUnicode=true&characterEncoding=utf8")
.username("activiti")
.password("definesys")
.driverClassName("com.mysql.jdbc.Driver")
.build();
}
}
这里为了简单把连接信息写死在代码里,不是一种好的方式,你可以将连接信息放到application.properties里。
- 修改pom文件去掉h2的依赖增加mysql驱动
....
<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>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
- 重新运行程序
重新调用start
接口后,流程发起后,会在数据库表ACT_RU_TASK
中创建记录。
总结
本文介绍了一个最简单的activiti流程在spring boot中的应用。
本文所有代码已经上传至github,仓库地址为https://github.com/wls1036/springboot-activiti6-tutorial欢迎star
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。