“This is the 13th day of my participation in the Gwen Challenge in November. Check out the details: The Last Gwen Challenge in 2021”

Author: Tangyuan

Personal blog: Javalover.cc

preface

Earlier we looked at getting started with a REST API;

In this article we will introduce the most common way to integrate with Spring Boot

Flowable already has a Spring Boot-based starter that we can introduce directly

directory

  1. Create a Spring Boot project
  2. Introduce the Flowable Starter dependency
  3. Creating a process definition
  4. Test deployment status
  5. Modifying a Database
  6. Provides REST interfaces externally

The body of the

1. Create a Spring Boot project

Here we use IDEA to create directly, and the directory after successful creation is as follows:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>
Copy the code

2. Introduce the Flowable starter dependency

We first introduce flowable-spring-boot-starter and H2 dependencies;

There are other dependencies, as follows:

<dependencies>
    <dependency>
        <groupId>org.flowable</groupId>
        <artifactId>flowable-spring-boot-starter</artifactId>
        <version>6.7.0</version>
    </dependency>
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-configuration-processor</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>
Copy the code

After importing the dependency, we can start the Spring Boot program and view the print log as follows:

The 2021-11-09 11:55:41. 8304-200 the INFO/restartedMain C.J.S.S pringBootFlowableDemoApplication: Started SpringBootFlowableDemoApplicationin55.805 seconds (JVM is runningfor 64.253)
Copy the code

If you see this line, the startup is successful;

Here are a few things to note:

  • When Spring Boot starts, an H2 database is automatically created to store flowable data
  • All process engine-related beans are created
  • Resources directory:
    • BPMN process definitions in the Processes directory are automatically deployed.
    • Case, DMN, Forms, and other directories are also deployed

3. Create the process definition

Here we create a process definition, the path is: the SRC/main/resources/the processes/one – a task – process. Bpmn20. XML


      
<definitions
        xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
        xmlns:flowable="http://flowable.org/bpmn"
        targetNamespace="Examples">

    <process id="oneTaskProcess" name="The One Task Process">
        <startEvent id="theStart" />
        <sequenceFlow id="flow1" sourceRef="theStart" targetRef="theTask" />
        <userTask id="theTask" name="my task" flowable:assignee="jalon" />
        <sequenceFlow id="flow2" sourceRef="theTask" targetRef="theEnd" />
        <endEvent id="theEnd" />
    </process>

</definitions>
Copy the code

4. Test the deployment status

Now we write a test method to determine if the above bPMn.xml file was successfully deployed:

package com.jalon.springbootflowabledemo;

import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;

@SpringBootApplication
public class SpringBootFlowableDemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootFlowableDemoApplication.class, args);
    }
    
    @Bean
    public CommandLineRunner init(final RepositoryService repositoryService,
                                  final RuntimeService runtimeService,
                                  final TaskService taskService) {

        return strings -> {
            System.out.println("Number of process definitions : "
                    + repositoryService.createProcessDefinitionQuery().count());
            System.out.println("Number of tasks : " + taskService.createTaskQuery().count());
            runtimeService.startProcessInstanceByKey("oneTaskProcess");
            System.out.println("Number of tasks after process start: "+ taskService.createTaskQuery().count()); }; }}Copy the code

Here we have registered a CommandLineRunner Bean, which is executed when Spring Boot is started;

Then restart the application and print the following: The deployment is successful

Number of process definitions : 1
Number of tasks : 0
Number of tasks after process start: 1
Copy the code

As you can see from the print, a process definition is deployed and a process task is started;

If you restart the application at this point, the process task is still the same;

Because the default database h2, data will be lost after restart;

Now we can change it to MySQL

5. Modify the database

First, you need to modify the dependencies, remove the H2 dependencies, introduce the mysql driver, and configure the database parameters

 <dependency>
     <groupId>mysql</groupId>
     <artifactId>mysql-connector-java</artifactId>
     <version>8.0.11</version>
</dependency>
Copy the code

Modify application.yml to add database configuration:

spring:
  datasource:
    url: JDBC: mysql: / / 127.0.0.1:3306 / flowable - spring - the boot? characterEncoding=UTF-8&serverTimezone=UTC&useSSL=false
    username: root
    password: root
Copy the code

Create a database flowable-spring-boot locally

Then restart the application: When it starts, Flowable automatically creates tables and populates them with data

The 2021-11-09 12:32:22. 7944-329 the INFO/restartedMain C.J.S.S pringBootFlowableDemoApplication: Started SpringBootFlowableDemoApplicationin267.496 seconds (JVM is runningfor275.771) Number of process definitions: 1 Number of tasks: 0 Number of tasks after process start: 1Copy the code

At this time, the printed process task is 1, and then we restart for several times, we will find that the number of tasks is increasing.

If it is an H2 database, it will not increase because the H2 database is memory based and the memory data is cleared after the restart.

6. Provide REST interfaces externally

By providing external interfaces, users can easily interact with each other on the interface, including process startup, approval, and query

We will create a Flowable Service that contains two methods, one is to start the flow and one is to query the task (by the assigned user name).

package com.jalon.springbootflowabledemo;

import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.task.api.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
public class MyService {

    @Autowired
    private RuntimeService runtimeService;

    @Autowired
    private TaskService taskService;

    @Transactional
    public void startProcess(a) {
        runtimeService.startProcessInstanceByKey("oneTaskProcess");
    }

    @Transactional
    public List<Task> getTasks(String assignee) {
        returntaskService.createTaskQuery().taskAssignee(assignee).list(); }}Copy the code

The above runtimeService. StartProcessInstanceByKey (” oneTaskProcess “); Key is the process ID in the process definition:

 <process id="oneTaskProcess" name="The One Task Process">
Copy the code

Create a new controller to handle user requests:

package com.jalon.springbootflowabledemo;

import lombok.Data;
import org.flowable.task.api.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

@RestController
public class MyRestController {

    @Autowired
    private MyService myService;

    @PostMapping(value="/process")
    public void startProcessInstance(a) {
        myService.startProcess();
    }

    @RequestMapping(value="/tasks", method= RequestMethod.GET, produces= MediaType.APPLICATION_JSON_VALUE)
    public List<TaskRepresentation> getTasks(@RequestParam String assignee) {
        List<Task> tasks = myService.getTasks(assignee);
        List<TaskRepresentation> dtos = new ArrayList<TaskRepresentation>();
        for (Task task : tasks) {
            dtos.add(new TaskRepresentation(task.getId(), task.getName()));
        }
        return dtos;
    }

    @Data
    static class TaskRepresentation {

        private String id;
        private String name;

        public TaskRepresentation(String id, String name) {
            this.id = id;
            this.name = name; }}}Copy the code

Here we define a data transmission object TaskRepresentation, which encapsulates the data returned externally. The encapsulated data are task ID and task name.

Next we restart the application and send the request through Postman;

Start an instance:

curl -X POST  http://localhost:8080/process
Copy the code

Query task:

curl http://localhost:8080/tasks? assignee=kermitCopy the code

The assignee parameter here is the assignee configured in XML

<userTask id="theTask" name="my task" flowable:assignee="jalon" />
Copy the code

Here I have multiple tasks because I started it several times

The source code

I uploaded it to Github

conclusion

This article mainly introduces the integration of Flowable into SpringBoot, MySQL database configuration, provide REST support and other content;

As you can see, once integrated into Spring Boot, it is very easy to use;