SpringBoot + Flowable的入门篇,完整例子
一、Flowable简介
Flowable是什么
Flowable是一个使用Java编写的轻量级业务流程引擎。Flowable流程引擎可用于部署BPMN 2.0流程定义(用于定义流程的行业XML标准), 创建这些流程定义的流程实例,进行查询,访问运行中或历史的流程实例与相关数据,等等。
Flowable可以十分灵活地加入你的应用/服务/构架。可以将JAR形式发布的Flowable库加入应用或服务,来嵌入引擎。 以JAR形式发布使Flowable可以轻易加入任何Java环境:Java SE;Tomcat、Jetty或Spring之类的servlet容器;JBoss或WebSphere之类的Java EE服务器,等等。 另外,也可以使用Flowable REST API进行HTTP调用。也有许多Flowable应用(Flowable Modeler, Flowable Admin, Flowable IDM 与 Flowable Task),提供了直接可用的UI示例,可以使用流程与任务。
所有使用Flowable方法的共同点是核心引擎。核心引擎是一组服务的集合,并提供管理与执行业务流程的API。 下面的教程从设置与使用核心引擎的介绍开始。
开始
1、创建一个springboot项目,添加依赖
<!-- Flowable spring-boot  --> <dependency>     <groupId>org.flowable</groupId>     <artifactId>flowable-spring-boot-starter</artifactId>     <version>6.4.1</version> </dependency>
  <!--MySQL驱动,这里采用MySQL数据库,如果采用其它数据库,需要引入对应的依赖。--> <dependency>     <groupId>mysql</groupId>     <artifactId>mysql-connector-java</artifactId>     <version>8.0.15</version> </dependency>
  <!-- Flowable 内部日志采用 SLF4J --> <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> 复制代码
   | 
 
resource 目录下新建文件 log4j.properties
log4j.rootLogger=DEBUG, CA log4j.appender.CA=org.apache.log4j.ConsoleAppender log4j.appender.CA.layout=org.apache.log4j.PatternLayout log4j.appender.CA.layout.ConversionPattern= %d{hh:mm:ss,SSS} [%t] %-5p %c %x - %m%n 复制代码
   | 
 
2、初始化 ProcessEngine
我的配置文件 ProcessEngineConfig.java
依赖
<!-- 配置文件处理器 --> <dependency>      <groupId>org.springframework.boot</groupId>      <artifactId>spring-boot-configuration-processor</artifactId>  </dependency>  <!-- lombok --> <dependency>     <groupId>org.projectlombok</groupId>     <artifactId>lombok</artifactId>     <version>1.18.0</version>     <scope>provided</scope> </dependency> 复制代码
   | 
 
配置文件 ProcessEngineConfig.java
/**  * 流程引擎配置文件  * @author: linjinp  * @create: 2019-10-21 16:49  **/ @Configuration @ConfigurationProperties(prefix = "spring.datasource") @Data public class ProcessEngineConfig {
      private Logger logger = LoggerFactory.getLogger(ProcessEngineConfig.class);
      @Value("${spring.datasource.url}")     private String url;
      @Value("${spring.datasource.driver-class-name}")     private String driverClassName;
      @Value("${spring.datasource.username}")     private String username;
      @Value("${spring.datasource.password}")     private String password;
      /**      * 初始化流程引擎      * @return      */     @Primary     @Bean(name = "processEngine")     public ProcessEngine initProcessEngine() {         logger.info("=============================ProcessEngineBegin=============================");
          // 流程引擎配置         ProcessEngineConfiguration cfg = null;
          try {             cfg = new StandaloneProcessEngineConfiguration()                     .setJdbcUrl(url)                     .setJdbcUsername(username)                     .setJdbcPassword(password)                     .setJdbcDriver(driverClassName)                     // 初始化基础表,不需要的可以改为 DB_SCHEMA_UPDATE_FALSE                     .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE)                     // 默认邮箱配置                     // 发邮件的主机地址,先用 QQ 邮箱                     .setMailServerHost("smtp.qq.com")                     // POP3/SMTP服务的授权码                     .setMailServerPassword("xxxxxxx")                     // 默认发件人                     .setMailServerDefaultFrom("1010338399@qq.com")                     // 设置发件人用户名                     .setMailServerUsername("管理员")                     // 解决流程图乱码                     .setActivityFontName("宋体")                     .setLabelFontName("宋体")                     .setAnnotationFontName("宋体");         } catch (Exception e) {             e.printStackTrace();         }         // 初始化流程引擎对象         ProcessEngine processEngine = cfg.buildProcessEngine();         logger.info("=============================ProcessEngineEnd=============================");         return processEngine;     } } 复制代码
   | 
 
启动项目后,会自动创建flowable的数据库表
flowable命名规则:
- ACT_RE_* :’ RE ’表示repository(存储)。RepositoryService接口操作的表。带此前缀的表包含的是静态信息,如,流程定义,流程的资源(图片,规则等)。
 
- ACT_RU_* :’ RU ’表示runtime。这是运行时的表存储着流程变量,用户任务,变量,职责(job)等运行时的数据。flowable只存储实例执行期间的运行时数据,当流程实例结束时,将删除这些记录。这就保证了这些运行时的表小且快。
 
- ACT_ID_* : ’ ID ’表示identity(组织机构)。这些表包含标识的信息,如用户,用户组,等等。
 
- ACT_HI_* : ’ HI ’表示history。就是这些表包含着历史的相关数据,如结束的流程实例,变量,任务,等等。
 
- ACT_GE_* : 普通数据,各种情况都使用的数据。
 
3、部署流程定义
要构建的流程是一个非常简单的请假流程。Flowable引擎需要流程定义为BPMN 2.0格式,这是一个业界广泛接受的XML标准。
在Flowable术语中,我们将其称为一个流程定义(process definition)。一个流程定义可以启动多个流程实例(process instance)。流程定义可以看做是重复执行流程的蓝图。 在这个例子中,流程定义定义了请假的各个步骤,而一个流程实例对应某个雇员提出的一个请假申请。
BPMN 2.0存储为XML,并包含可视化的部分:使用标准方式定义了每个步骤类型(人工任务,自动服务调用,等等)如何呈现,以及如何互相连接。这样BPMN 2.0标准使技术人员与业务人员能用双方都能理解的方式交流业务流程。
我们要使用的流程定义为:
在src/main/resources文件夹下创建为employeeLeave.bpmn20.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:flowable="http://flowable.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.flowable.org/processdef" exporter="Flowable Open Source Modeler">     <process id="employeeLeave" name="职工请假流程" isExecutable="true">         <documentation>职工请假</documentation>         <startEvent id="bsin1" flowable:formKey="employeeLeave" flowable:formFieldValidation="true"></startEvent>         <userTask id="bsin3" name="经理" flowable:assignee="${auditor}" flowable:formFieldValidation="true">             <extensionElements>                 <modeler:initiator-can-complete xmlns:modeler="http://flowable.org/modeler"><![CDATA[false]]></modeler:initiator-can-complete>             </extensionElements>         </userTask>         <serviceTask id="bsin2" name="服务任务"></serviceTask>         <endEvent id="sid-74F2CDB2-1D4F-4DD4-B848-51158EE18A84"></endEvent>         <sequenceFlow id="sid-DB4E84AD-78A8-4F7F-B14F-682A7FC92790" sourceRef="bsin1" targetRef="bsin2"></sequenceFlow>         <sequenceFlow id="sid-23FB4CEA-43F8-46E8-9690-6E6C038491D4" sourceRef="bsin2" targetRef="bsin3"></sequenceFlow>         <sequenceFlow id="sid-E818BD0A-E382-4B16-97DB-5AEE4825A4B3" sourceRef="bsin3" targetRef="sid-74F2CDB2-1D4F-4DD4-B848-51158EE18A84"></sequenceFlow>     </process>     <bpmndi:BPMNDiagram id="BPMNDiagram_employeeLeave">         <bpmndi:BPMNPlane bpmnElement="employeeLeave" id="BPMNPlane_employeeLeave">             <bpmndi:BPMNShape bpmnElement="bsin1" id="BPMNShape_bsin1">                 <omgdc:Bounds height="30.0" width="30.0" x="100.0" y="160.0"></omgdc:Bounds>             </bpmndi:BPMNShape>             <bpmndi:BPMNShape bpmnElement="bsin3" id="BPMNShape_bsin3">                 <omgdc:Bounds height="80.0" width="100.0" x="465.0" y="135.0"></omgdc:Bounds>             </bpmndi:BPMNShape>             <bpmndi:BPMNShape bpmnElement="bsin2" id="BPMNShape_bsin2">                 <omgdc:Bounds height="80.0" width="100.0" x="240.0" y="135.0"></omgdc:Bounds>             </bpmndi:BPMNShape>             <bpmndi:BPMNShape bpmnElement="sid-74F2CDB2-1D4F-4DD4-B848-51158EE18A84" id="BPMNShape_sid-74F2CDB2-1D4F-4DD4-B848-51158EE18A84">                 <omgdc:Bounds height="28.0" width="28.0" x="708.8" y="159.0"></omgdc:Bounds>             </bpmndi:BPMNShape>             <bpmndi:BPMNEdge bpmnElement="sid-23FB4CEA-43F8-46E8-9690-6E6C038491D4" id="BPMNEdge_sid-23FB4CEA-43F8-46E8-9690-6E6C038491D4" flowable:sourceDockerX="50.0" flowable:sourceDockerY="40.0" flowable:targetDockerX="50.0" flowable:targetDockerY="40.0">                 <omgdi:waypoint x="339.94999999983776" y="175.0"></omgdi:waypoint>                 <omgdi:waypoint x="465.0" y="175.0"></omgdi:waypoint>             </bpmndi:BPMNEdge>             <bpmndi:BPMNEdge bpmnElement="sid-DB4E84AD-78A8-4F7F-B14F-682A7FC92790" id="BPMNEdge_sid-DB4E84AD-78A8-4F7F-B14F-682A7FC92790" flowable:sourceDockerX="15.0" flowable:sourceDockerY="15.0" flowable:targetDockerX="50.0" flowable:targetDockerY="40.0">                 <omgdi:waypoint x="129.94999940317362" y="175.0"></omgdi:waypoint>                 <omgdi:waypoint x="240.0" y="175.0"></omgdi:waypoint>             </bpmndi:BPMNEdge>             <bpmndi:BPMNEdge bpmnElement="sid-E818BD0A-E382-4B16-97DB-5AEE4825A4B3" id="BPMNEdge_sid-E818BD0A-E382-4B16-97DB-5AEE4825A4B3" flowable:sourceDockerX="50.0" flowable:sourceDockerY="40.0" flowable:targetDockerX="14.0" flowable:targetDockerY="14.0">                 <omgdi:waypoint x="564.95" y="175.0"></omgdi:waypoint>                 <omgdi:waypoint x="636.9" y="175.0"></omgdi:waypoint>                 <omgdi:waypoint x="636.9" y="173.0"></omgdi:waypoint>                 <omgdi:waypoint x="708.8" y="173.0"></omgdi:waypoint>             </bpmndi:BPMNEdge>         </bpmndi:BPMNPlane>     </bpmndi:BPMNDiagram> </definitions> 复制代码
   | 
 
flowable有个8个核心服务,springboot里使用 flowable-spring-boot-starter 依赖,会自动帮忙注册好,不需要自己再注册,直接使用即可。
使用RepositoryService,可以通过XML文件的路径创建一个新的部署(Deployment),并调用deploy()方法实际执行:
// 部署流程 repositoryService.createDeployment()         .name("employeeLeave")         .addClasspathResource("employeeLeave.bpmn20.xml")         .deploy(); 复制代码
   | 
 
4、启动流程实例
现在已经在流程引擎中部署了流程定义,因此可以使用这个流程定义作为“蓝图”启动流程实例。
要启动流程实例,需要提供一些初始化流程变量。一般来说,可以通过呈现给用户的表单,或者在流程由其他系统自动触发时通过REST API,来获取这些变量。
启动流程实例有两种方式
runtimeService.startProcessInstanceByKey(processInstanceByKey,variables); 复制代码
   | 
 
runtimeService.startProcessInstanceById(processInstanceById,variables); 复制代码
   | 
 
variables就是用来存储流程变量的
5、查询与完成任务
flowable的任务有很多,常见的有服务任务和用户任务
职工通过表单填写的基本信息都会存储在流程变量,流程启动后,会经过服务任务,服务任务会职工信息分配代理人,将代理人信息添加到流程变量中 
 实现服务任务调用的服务,需要创建一个类,实现JavaDelegate接口,实现execute方法,这个方法可以写很多业务逻辑
public class ServiceTask implements JavaDelegate {
      @Autowired     private RuntimeService runtimeService;
      @Override     public void execute(DelegateExecution delegateExecution) {         // 业务逻辑我就不写了         final String executionId  = delegateExecution.getId();         runtimeService.setVariable(executionId,"assignee","admin");     } } 复制代码
  | 
 
在流转到用户任务之前,我们需要设置代理人,我们可以使用用户任务监听器动态设置代理人
public class UserTaskListener implements TaskListener {     @Autowired     private TaskService taskService;     /**      * 用户任务监听器      */     @Override     public void notify(DelegateTask delegateTask) {         String taskId = delegateTask.getId();         Map<String, Object> assignee = taskService.getVariables(taskId);         // 设置办理人         taskService.setAssignee(taskId, (String) assignee.get("assignee"));     } 复制代码
  | 
 
用户要获得实际的任务列表,需要通过TaskService创建一个TaskQuery。
public List<Task> TaskQuery(String assignee) {     TaskQuery taskQuery = taskService.createTaskQuery();     List<Task> taskList = taskQuery.taskAssignee(assignee).list();     return taskList; } 复制代码
  | 
 
经理现在就可以完成任务了
taskService.complete(taskId,variables); 复制代码
   | 
 
欢迎加入我们:gitee.com/bsin-paas/a…

分类:
后端
标签:
后端
安装掘金浏览器插件
多内容聚合浏览、多引擎快捷搜索、多工具便捷提效、多模式随心畅享,你想要的,这里都有!
前往安装
评论
相关推荐

我是稻草人 
 
获得点赞 16
文章被阅读 2,652

下载稀土掘金APP
一个帮助开发者成长的社区
相关文章
Flowable最新版6.7.0入门篇之基于JavaAPI的例子结合FlowableUI
6点赞
 · 
1评论SpringBoot+Vue+Flowable,模拟一个请假审批流程!
35点赞
 · 
2评论Spring Boot 整合流程引擎 Flowable,so easy!
56点赞
 · 
1评论SpringBoot+flowable快速实现工作流
61点赞
 · 
9评论SpringBoot整合Flowable工作流-2(代码整合)
7点赞
 · 
3评论
目录
稀土掘金浏览器插件——你的一站式工作台
多内容聚合浏览、多引擎快捷搜索、多工具便捷提效、多模式随心畅享,你想要的,这里都有。
×
拖拽到此处
图片将完成下载