Based workflow instance flowable work springboot implementation

Based workflow instance flowable work springboot implementation

Flowable Chinese official website https://tkjohn.github.io/flowable-userguide/#_deploying_a_process_definition
1, first create a blank project a springboot

2, here is the name of the project editor, I wrote here is flowabledemo

3, this position is selected configuration, as is the demo so I did not choose any configuration

4, entered here is the name of the output folder, and I chose the same project file name


5. Once created open project:

Adding flowable and mysql rely on pomx years (generate a database to use), I chose the MySQL database, because there are ready-mysql on my computer

<dependency>
    <groupId>org.flowable</groupId>
    <artifactId>flowable-engine</artifactId>
    <version>6.5.0-SNAPSHOT</version>
  </dependency>
 <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.45</version>
 </dependency>
6, this time he will automatically download the appropriate file, waiting for something a little longer, we can go to add a new database, after already use.

New flowable database (database name set their own)

7, and then add the database information inlet portion in the main function (to automatically generates the table required, the original sentence comment is required, or deleted)
//        SpringApplication.run(FlowabledemoApplication.class, args);
ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration()
        .setJdbcUrl("jdbc:mysql://localhost:3306/flowable")
        .setJdbcUsername("root")
        .setJdbcPassword("123456")
        .setJdbcDriver("com.mysql.jdbc.Driver")
        .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
ProcessEngine processEngine = cfg.buildProcessEngine();

8, then right operation, generation of database information. Then the console will output the contents of a long, until the output stops, to view the database, you will find a lot of new flowable database table, this operation can be continued.

At runtime instance, with regard to the new database does not need this part of the code is commented out (if there are updates of the database will automatically update the database content).


9, and then leave for an example of writing of:

We need to add a new folder resource profile holiday-request.bpmn20.xml, which reads:

<?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="Holiday Request" isExecutable="true">
        <startEvent id="startEvent"/>
        <sequenceFlow sourceRef="startEvent" targetRef="approveTask"/>
        <userTask id="approveTask" name="Approve or reject request" flowable:candidateGroups="managers"/>
        <sequenceFlow sourceRef="approveTask" targetRef="decision"/>
        <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="com.flowable.flowabledemo.CallExternalSystemDelegate"/>
        <sequenceFlow sourceRef="externalSystemCall" targetRef="holidayApprovedTask"/>
        <userTask id="holidayApprovedTask" name="Holiday approved" flowable:assignee="${employee}"/>
        <sequenceFlow sourceRef="holidayApprovedTask" targetRef="approveEnd"/>
        <serviceTask id="sendRejectionMail" name="Send out rejection email"
                     flowable:class="com.flowable.flowabledemo.SendRejectionMail"/>
<!--这里的class需要注意,后边跟的路径是你项目类问价所在的相对位置,若运行的时候报错,需要来修改这里的位置代码-->
        <sequenceFlow sourceRef="sendRejectionMail" targetRef="rejectEnd"/>
        <endEvent id="approveEnd"/>
        <endEvent id="rejectEnd"/>
    </process>
</definitions>
10, then the following additional entry in the function (main)
/**
 * 部署工作流文件到流程引擎,其实就是将xml文件解析成Java对象,从而可以在程序里使用.
 */
RepositoryService repositoryService = processEngine.getRepositoryService();
Deployment deployment = repositoryService.createDeployment()
        .addClasspathResource("holiday-request.bpmn20.xml")
        .deploy();
/**
 * API使用
 */
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
        .deploymentId(deployment.getId())
        .singleResult();
System.out.println("Found process definition : " + processDefinition.getName());
/**
 * 初始化流程变量
 */
Scanner scanner= new Scanner(System.in);
System.out.println("Who are you?");
String employee = scanner.nextLine();
System.out.println("How many holidays do you want to request?");
Integer nrOfHolidays = Integer.valueOf(scanner.nextLine());
System.out.println("Why do you need them?");
String description = scanner.nextLine();
/**
 * 通过RuntimeService启动一个流程实例,简称“启动流程”,这里就是启动请假流程
 */
RuntimeService runtimeService = processEngine.getRuntimeService();
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("employee", employee);
variables.put("nrOfHolidays", nrOfHolidays);
variables.put("description", description);
ProcessInstance processInstance =
        runtimeService.startProcessInstanceByKey("holidayRequest", variables);
/**
 * 查询某个用户的任务
 */
TaskService taskService = processEngine.getTaskService();
List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("managers").list();
System.out.println("You have " + tasks.size() + " tasks:");
for (int i=0; i<tasks.size(); i++) {
    System.out.println((i+1) + ") " + tasks.get(i).getName() + " created by [" + taskService.getVariables(tasks.get(i).getId()).get("employee") + "]");
}
/**
 * 根据任务获取到这个任务涉及的流程变量
 */
System.out.println("Which task would you like to complete?");
int taskIndex = Integer.valueOf(scanner.nextLine());
Task task = tasks.get(taskIndex - 1);
Map<String, Object> processVariables = taskService.getVariables(task.getId());
System.out.println(processVariables.get("employee") + " wants " +
        processVariables.get("nrOfHolidays") + " of holidays. Do you approve this?");

/**
 * 如果是y,则流程结束
 */
boolean approved = scanner.nextLine().toLowerCase().equals("y");
variables = new HashMap<String, Object>();
variables.put("approved", approved);
taskService.complete(task.getId(), variables);

/**
 * 查询历史数据,每个步骤的花费的时间
 */
HistoryService historyService = processEngine.getHistoryService();
List<HistoricActivityInstance> activities =
        historyService.createHistoricActivityInstanceQuery()
                .processInstanceId(processInstance.getId())
                .finished()
                .orderByHistoricActivityInstanceEndTime().asc()
                .list();

for (HistoricActivityInstance activity : activities) {
    System.out.println(activity.getActivityId() + " took "
            + activity.getDurationInMillis() + " milliseconds");
}
11, and then need to create a class file in the same directory content CallExternalSystemDelegate main function is:
package com.flowable.flowabledemo;
import org.flowable.engine.delegate.DelegateExecution;
import org.flowable.engine.delegate.JavaDelegate;

public class CallExternalSystemDelegate implements JavaDelegate {
    public void execute(DelegateExecution execution) {
        System.out.println("Calling the external system for employee "
                + execution.getVariable("employee"));
    }
}
Directory hierarchy display

13, run shot:

This time employee status to operate.
Followed by input: long leave of absence when the reason for the name of leave

14, hit Enter, this time will enter the manager's role, which will let you choose a leave transaction, shows there are 16 tasks, you can scroll up to view the contents of a specific number, we just create a new task number is 14, so enter here 14, hit enter to continue

15, this time will list the names of those who leave, long leave, you need to enter y to agree to this request for leave.

16, and then pressing the return, the program is completed, and outputs the information.

Thus, a simple workflow instance flowable work even if it is done!

Click to download the source files
point I Touch Me

Guess you like

Origin www.cnblogs.com/nanstar/p/11935133.html