【Flowable】Springboot使用Flowable(一)

一、项目依赖

xml 复制代码
<dependency>
            <groupId>org.flowable</groupId>
            <artifactId>flowable-engine</artifactId>
            <version>6.3.0</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.21</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.21</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.21</version>
        </dependency>

二、新建Test类

java 复制代码
public class Test01 {

    /**
     * 获取流程引擎对象
     */
    @Test
    public void testProcessEngine() {
        // 获取 ProcessEngineConfiguration 对象
        ProcessEngineConfiguration configuration = new StandaloneProcessEngineConfiguration();

        //配置相关的数据库连接信息
        configuration.setJdbcDriver("com.mysql.cj.jdbc.Driver");
        configuration.setJdbcUsername("xxx");
        configuration.setJdbcPassword("xxx");
        configuration.setJdbcUrl("jdbc:mysql://xxx/flowable?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai");
        //如果数据库中的表结构不存在就新建
        configuration.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);

        //构建流程引擎对象
        ProcessEngine processEngine = configuration.buildProcessEngine();
        System.out.println("processEngine = " + processEngine);
    }

    ProcessEngineConfiguration configuration = null;


    @Before
    public void before() {
        // 获取 ProcessEngineConfiguration 对象
        configuration = new StandaloneProcessEngineConfiguration();

        //配置相关的数据库连接信息
        configuration.setJdbcDriver("com.mysql.cj.jdbc.Driver");
        configuration.setJdbcUsername("xxxx");
        configuration.setJdbcPassword("xxxx");
        configuration.setJdbcUrl("jdbc:mysql://xxxxx/flowable?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai");
        //如果数据库中的表结构不存在就新建
        configuration.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
    }


    /**
     * 部署流程
     */
    @Test
    public void testDeploy() {
        //1.获取ProcessEngine 对象
        ProcessEngine processEngine = configuration.buildProcessEngine();
        //2.获取RepositoryService
        RepositoryService repositoryService = processEngine.getRepositoryService();
        //3.完成流程部署操作
        Deployment deploy = repositoryService.createDeployment()
                .addClasspathResource("test.bpmn20.xml") //关联要部署的流程名称
                .name("请假流程")
                .deploy(); //部署流程


        System.out.println("id: " + deploy.getId());
        System.out.println("name: " + deploy.getName());
        System.out.println("key: " + deploy.getKey());

    }

    /**
     * 查询部署流程的定义信息
     */
    @Test
    public void testDeployQuery() {
        ProcessEngine processEngine = configuration.buildProcessEngine();

        RepositoryService repositoryService = processEngine.getRepositoryService();
        //创建流程查询对象
        ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();

        ProcessDefinition processDefinition = processDefinitionQuery.deploymentId("15001").singleResult();

        //部署的流程图ID,常用来做版本控制
        System.out.println("processDefinition.getDeploymentId() = " + processDefinition.getDeploymentId());
        //流程名称
        System.out.println("processDefinition.getName() = " + processDefinition.getName());
        //流程描述
        System.out.println("processDefinition.getDescription() = " + processDefinition.getDescription());
        //流程图id
        System.out.println("processDefinition.getId() = " + processDefinition.getId());
        //流程唯一标识
        System.out.println("processDefinition.getKey() = " + processDefinition.getKey());
    }

    /**
     * 删除部署的流程
     */
    @Test
    public void testDeleteDeploy() {
        ProcessEngine processEngine = configuration.buildProcessEngine();
        RepositoryService repositoryService = processEngine.getRepositoryService();
        //删除部署ID为1的,如果部署的流程启动了 则没法删除
//        repositoryService.deleteDeployment("1");
        // 第二个参数是级联删除,如果流程启动了也可以进行删除,相关的任务也会被删除
        repositoryService.deleteDeployment("7501", true);
    }

    /**
     * 启动流程
     */
    @Test
    public void testStartProcess() {
        //id :2501
        ProcessEngine processEngine = configuration.buildProcessEngine();
        //通过runtimeService 启动流程实例
        RuntimeService runtimeService = processEngine.getRuntimeService();


        //构建流程变量
        Map<String, Object> variable = new HashMap<>();
        variable.put("employee", "张三");
        variable.put("nrOfHolidays", 3);
        variable.put("description", "感冒了");
        //启动流程实例
        ProcessInstance holidayRequest = runtimeService.startProcessInstanceByKey("test", variable);

        //流程实例ID
        System.out.println("holidayRequest.getProcessInstanceId() = " + holidayRequest.getProcessInstanceId());
        System.out.println("holidayRequest.getProcessDefinitionId() = " + holidayRequest.getProcessDefinitionId());
        System.out.println("holidayRequest.getActivityId() = " + holidayRequest.getActivityId());
    }

    /**
     * 查询代办
     */
    @Test
    public void testQueryTask() {

        ProcessEngine processEngine = configuration.buildProcessEngine();

        TaskService taskService = processEngine.getTaskService();

        TaskQuery taskQuery = taskService.createTaskQuery();
        List<Task> list = taskQuery.processDefinitionKey("holidayRequest")
//                .taskAssignee("zhangsan")
                .taskDefinitionId("test:1:15004")
                .list();

        for (Task task : list) {
            System.out.println("task.getProcessDefinitionId() = " + task.getProcessDefinitionId());
            System.out.println("task.getName() = " + task.getName());
            System.out.println("task.getAssignee() = " + task.getAssignee());
            System.out.println("task.getDescription() = " + task.getDescription());
            System.out.println("task.getId() = " + task.getId());
        }
    }


    /**
     * 处理完成当前任务
     */
    @Test
    public void testCompleteTask() {
        ProcessEngine processEngine = configuration.buildProcessEngine();

        TaskService taskService = processEngine.getTaskService();

        Task task = taskService.createTaskQuery()
                .processDefinitionKey("test")
                .taskAssignee("zhangsan")
                .singleResult();

        //创建流程变量
        HashMap<String, Object> variables = new HashMap<>();
        variables.put("approved", false);
        //完成任务
        taskService.complete(task.getId(), variables);
    }


    /**
     * 获取流程历史信息
     */
    @Test
    public void testHistory(){
        ProcessEngine processEngine = configuration.buildProcessEngine();

        HistoryService historyService = processEngine.getHistoryService();

        List<HistoricActivityInstance> list = historyService.createHistoricActivityInstanceQuery()
                .processInstanceId("17501")
                .finished()
                .orderByHistoricActivityInstanceEndTime().asc()
                .list();

        for (HistoricActivityInstance historicActivityInstance : list) {

            System.out.println("historicActivityInstance.getActivityId() = " + historicActivityInstance.getActivityId());
            System.out.println("historicActivityInstance.getActivityName() = " + historicActivityInstance.getActivityName());
            System.out.println("historicActivityInstance.getTaskId() = " + historicActivityInstance.getTaskId());
            System.out.println("historicActivityInstance.getAssignee() = " + historicActivityInstance.getAssignee());
            System.out.println("historicActivityInstance.getDeleteReason() = " + historicActivityInstance.getDeleteReason());
            System.out.println("处理时间:historicActivityInstance.getDurationInMillis() = " + historicActivityInstance.getDurationInMillis());
            System.out.println("------------------");
        }
    }
}

三、flowable流程图

  • 新建一个xml文件命名为:holiday-request.bpmn20.xml
xml 复制代码
<?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">
	  <!--id:流程主键 name:流程名称 -->
    <process id="holidayRequest" name="qingjia" isExecutable="true">
       <!--startEvent:开始事件-->
        <startEvent id="startEvent"/>
         <!--sequenceFlow顺序流  sourceRef:源  targetRef:目标ID-->
        <sequenceFlow sourceRef="startEvent" targetRef="approveTask"/>
         <!--userTask:用户任务-->
        <userTask id="approveTask" name="tongyi or reject" flowable:assignee="zhangsan"/>
        <sequenceFlow sourceRef="approveTask" targetRef="decision"/>
        <!--exclusiveGateway:排他网关-->
        <exclusiveGateway id="decision"/>
        <sequenceFlow sourceRef="decision" targetRef="externalSystemCall">
            <conditionExpression xsi:type="tFormalExpression">
                <![CDATA[
          ${approved}
        ]]>
            </conditionExpression>
        </sequenceFlow>
        <sequenceFlow sourceRef="decision" targetRef="sendRejectionMail">
            <conditionExpression xsi:type="tFormalExpression">
                <![CDATA[
          ${!approved}
        ]]>
            </conditionExpression>
        </sequenceFlow>

        <serviceTask id="externalSystemCall" name="Enter holidays in external system"
                     flowable:class="org.flowable.CallExternalSystemDelegate"/>
        <sequenceFlow sourceRef="externalSystemCall" targetRef="holidayApprovedTask"/>

        <userTask id="holidayApprovedTask" name="Holiday approved"/>
        <sequenceFlow sourceRef="holidayApprovedTask" targetRef="approveEnd"/>

        <serviceTask id="sendRejectionMail" name="Send out rejection email"
                     flowable:class="org.flowable.SendRejectionMail"/>
        <sequenceFlow sourceRef="sendRejectionMail" targetRef="rejectEnd"/>

        <endEvent id="approveEnd"/>

        <endEvent id="rejectEnd"/>
    </process>

</definitions>

以上简单介绍springboot整合flowable,后续会继续深入研究,欢迎各位小伙伴指点不足。

相关推荐
懒羊羊不懒@16 分钟前
Java基础语法—最小单位、及注释
java·c语言·开发语言·数据结构·学习·算法
ss27319 分钟前
手写Spring第4弹: Spring框架进化论:15年技术变迁:从XML配置到响应式编程的演进之路
xml·java·开发语言·后端·spring
DokiDoki之父31 分钟前
MyBatis—增删查改操作
java·spring boot·mybatis
兩尛1 小时前
Spring面试
java·spring·面试
舒一笑1 小时前
🚀 PandaCoder 2.0.0 - ES DSL Monitor & SQL Monitor 震撼发布!
后端·ai编程·intellij idea
Java中文社群1 小时前
服务器被攻击!原因竟然是他?真没想到...
java·后端
Full Stack Developme1 小时前
java.nio 包详解
java·python·nio
零千叶1 小时前
【面试】Java JVM 调优面试手册
java·开发语言·jvm
代码充电宝2 小时前
LeetCode 算法题【简单】290. 单词规律
java·算法·leetcode·职场和发展·哈希表
li3714908902 小时前
nginx报400bad request 请求头过大异常处理
java·运维·nginx