springboot整合flowable


前言

Flowable是一个使用Java编写的轻量级业务流程引擎,可以实现需要工作流的业务流程。

一、环境

1、引入依赖

引入 flowable 相关依赖

<!-- https://mvnrepository.com/artifact/org.flowable/flowable-spring-boot-starter -->
<dependency>
    <groupId>org.flowable</groupId>
    <artifactId>flowable-spring-boot-starter</artifactId>
    <version>6.7.2</version>
</dependency>

<!-- https://mvnrepository.com/artifact/xerces/xercesImpl -->
<dependency>
    <groupId>xerces</groupId>
    <artifactId>xercesImpl</artifactId>
    <version>2.12.2</version>
</dependency>

2、创建表

(1)自动创建表

打开配置

 flowable.database-schema-update=true

自动创建表的语句都在各个模块的包下面

在这里插入图片描述

(2)手动创建表

下载官网的sql文件

https://documentation.flowable.com/latest/develop/dbs/overview

在这里插入图片描述

下载下来是db-scripts-3.11.0.zip,解压后如下图,从里面找出对应数据库的sql文件,导入到数据库中

在这里插入图片描述

数据库表如图所示:

在这里插入图片描述

3、配置文件

# standalone 模式
flowable.standalone.server.enabled=false
# 允许 bean overriding
spring.main.allow-bean-definition-overriding=true
# 关闭定时任务
flowable.async-executor-activate=false
# 检测身份信息
flowable.idm.enabled=false
# 生成数据库表
flowable.database-schema-update=false

二、bpmn文件

1、holiday-request.bpmn20.xml

将文件放在classpath下

<?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: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:flowable="http://flowable.org/bpmn"
             typeLanguage="http://www.w3.org/2001/XMLSchema"
             expressionLanguage="http://www.w3.org/1999/XPath"
             targetNamespace="http://www.flowable.org/processdef">

    <process id="holidayRequest" name="请假流程" isExecutable="true">
        <!--开始事件-->
        <startEvent id="startEvent"/>
        <!--顺序流,从 startEvent 到 approveTask-->
        <sequenceFlow sourceRef="startEvent" targetRef="approveTask"/>
        <!--用户任务,需要 assignee 来审批-->
        <userTask id="approveTask" name="同意或驳回请求" flowable:candidateGroups="managers" flowable:assignee="admin"/>
        <!--顺序流,从 approveTask 到 decision -->
        <sequenceFlow sourceRef="approveTask" targetRef="decision"/>
        <!--排他网关-->
        <exclusiveGateway id="decision"/>
        <!--顺序流,从 decision 到 successCall-->
        <sequenceFlow sourceRef="decision" targetRef="successCall">
            <conditionExpression xsi:type="tFormalExpression">
                <!--approved 为 true 时,该顺序流生效-->
                <![CDATA[
          ${approved}
        ]]>
            </conditionExpression>
        </sequenceFlow>
        <!--顺序流,从 decision 到 failedCall-->
        <sequenceFlow sourceRef="decision" targetRef="failedCall">
            <conditionExpression xsi:type="tFormalExpression">
                <!--approved 为 false 时,该顺序流生效-->
                <![CDATA[
          ${!approved}
        ]]>
            </conditionExpression>
        </sequenceFlow>
        <!--服务任务,审批通过 -->
        <serviceTask id="successCall" name="审批通过调用服务"
                     flowable:class="com.iscas.biz.flowable.ApprovalSuccessDelegate"/>
        <sequenceFlow sourceRef="successCall" targetRef="holidayApprovedTask"/>
        <userTask id="holidayApprovedTask" name="审批通过"/>
        <sequenceFlow sourceRef="holidayApprovedTask" targetRef="approveEnd"/>
        <!--服务任务,审批驳回 -->
        <serviceTask id="failedCall" name="审批驳回调用服务"
                     flowable:class="com.iscas.biz.flowable.ApprovalFailDelegate"/>
        <sequenceFlow sourceRef="failedCall" targetRef="rejectEnd"/>
        <!--结束事件-->
        <endEvent id="approveEnd"/>
        <endEvent id="rejectEnd"/>
    </process>
</definitions>

2、ApprovalSuccessDelegate

审批通过回调任务

public class ApprovalSuccessDelegate implements JavaDelegate {
    @Override
    public void execute(DelegateExecution execution) {
        System.out.println("审批通过了");
    }
}

3、ApprovalFailedDelegate

审批驳回回调任务

public class ApprovalFailedDelegate implements JavaDelegate {
    @Override
    public void execute(DelegateExecution execution) {
        System.out.println("审批驳回了");
    }
}

三、测试

1、测试类

@RunWith(SpringRunner.class)
@SpringBootTest(classes = BizApp.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class FlowableTest {
	
    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private HistoryService historyService;

}

2、部署流程

 	@Test
    public void createDeployment() {
        Deployment deployment = repositoryService.createDeployment()
                .addClasspathResource("holiday-request.bpmn20.xml")
                .deploy();
        System.out.println(deployment.getId());
    }

打印出流程id

ce2bb094-caaf-11ec-90e1-00ff2b067e93

3、获取流程定义

	@Test
    public void getProcessDefinition() {
        ProcessDefinition result = repositoryService.createProcessDefinitionQuery()
                .deploymentId("ce2bb094-caaf-11ec-90e1-00ff2b067e93")
                .singleResult();

        System.out.println("definitionId: " + result.getId());
        System.out.println("definition: " + JsonUtils.toJson(result));
    }

结果:

definitionId: holidayRequest:1:ce44dde6-caaf-11ec-90e1-00ff2b067e93
definition: {
    "id":"holidayRequest:1:ce44dde6-caaf-11ec-90e1-00ff2b067e93",
    "revision":1,
    "isInserted":false,
    "isUpdated":false,
    "isDeleted":false,
    "originalPersistentState":{
        "suspensionState":1,
        "category":"http://www.flowable.org/processdef"
    },
    "name":"请假流程",
    "key":"holidayRequest",
    "version":1,
    "category":"http://www.flowable.org/processdef",
    "deploymentId":"ce2bb094-caaf-11ec-90e1-00ff2b067e93",
    "resourceName":"holiday-request.bpmn20.xml",
    "tenantId":"",
    "isGraphicalNotationDefined":false,
    "hasStartFormKey":false,
    "suspensionState":1,
    "isIdentityLinksInitialized":false,
    "definitionIdentityLinkEntities":[

    ],
    "derivedVersion":0,
    "suspended":false,
    "graphicalNotationDefined":false,
    "inserted":false,
    "updated":false,
    "deleted":false
}

4、启动流程

模拟用户发起一个请假流程

	@Test
    public void startProcessDefinition() {
        Map<String, Object> variables = new HashMap<String, Object>();
        variables.put("employee", "张三");
        variables.put("nrOfHolidays", 3);
        variables.put("description", "有事请假");
        ProcessInstance processInstance =
                runtimeService.startProcessInstanceByKey("holidayRequest", variables);
    }

5、获取任务

用户发起流程后,相关的人员能够查询该任务

	@Test
    public void getTask() {
        List<Task> tasks = taskService.createTaskQuery()
                .active()
                .includeProcessVariables()
                .taskCandidateOrAssigned("admin")
                .list();
        System.out.println("You have " + tasks.size() + " tasks:");
        for (int i = 0; i < tasks.size(); i++) {
            Task task = tasks.get(i);
            System.out.println((i + 1) + ") " + "taskId: " + task.getId() + ", taskName: " + task.getName());
        }
    }

结果:

You have 1 tasks:
1) taskId: 696f2831-cab0-11ec-aa1d-00ff2b067e93, taskName: 同意或驳回请求

6、审批任务

查询到任务后,对任务进行审批

	@Test
    public void completeTask() {
        Map variables = new HashMap<String, Object>();
        variables.put("approved", true);
        taskService.complete("696f2831-cab0-11ec-aa1d-00ff2b067e93", variables);
    }

结果回调了 ApprovalSuccessDelegate ,打印出"审批通过了"

7、查询历史任务

任务完成审批以后,会作为历史任务存储起来

	@Test
    public void historyTask() {
        List<HistoricActivityInstance> list = historyService.createHistoricActivityInstanceQuery()
                .taskAssignee("admin")
                .finished()
                .list();
        list.stream().map(JsonUtils::toJson).forEach(System.out::println);
    }

结果:

{
    "id":"696c1af0-cab0-11ec-aa1d-00ff2b067e93",
    "revision":2,
    "isInserted":false,
    "isUpdated":false,
    "isDeleted":false,
    "originalPersistentState":{
        "executionId":"696b308d-cab0-11ec-aa1d-00ff2b067e93",
        "activityId":"approveTask",
        "transactionOrder":3,
        "durationInMillis":134771,
        "activityName":"同意或驳回请求",
        "endTime":"2022-05-03 15:14:51",
        "assignee":"admin",
        "taskId":"696f2831-cab0-11ec-aa1d-00ff2b067e93"
    },
    "processInstanceId":"696a9449-cab0-11ec-aa1d-00ff2b067e93",
    "processDefinitionId":"holidayRequest:1:ce44dde6-caaf-11ec-90e1-00ff2b067e93",
    "startTime":"2022-05-03 15:12:37",
    "endTime":"2022-05-03 15:14:51",
    "durationInMillis":134771,
    "transactionOrder":3,
    "activityId":"approveTask",
    "activityName":"同意或驳回请求",
    "activityType":"userTask",
    "executionId":"696b308d-cab0-11ec-aa1d-00ff2b067e93",
    "assignee":"admin",
    "taskId":"696f2831-cab0-11ec-aa1d-00ff2b067e93",
    "tenantId":"",
    "inserted":false,
    "updated":false,
    "deleted":false
}

  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_lrs

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值