网站搜索引擎优化推广,有什么平台可以发布推广信息,物流网站建设的背景,网站开发费用说明0、背景 现状#xff1a;公司各部门业务系统有各自的工作流引擎#xff0c;也有cross function的业务在不同系统或OA系统流转#xff0c;没有统一的去规划布局统一的BPM解决方案#xff0c;近期由于一个项目引发朝着整合统一的BPM方案#xff0c;特了解一下市面上比较主流…0、背景 现状公司各部门业务系统有各自的工作流引擎也有cross function的业务在不同系统或OA系统流转没有统一的去规划布局统一的BPM解决方案近期由于一个项目引发朝着整合统一的BPM方案特了解一下市面上比较主流的开源和收费的工作流引擎。本文主要介绍开源的工作流引擎flowable. 1、开源工作流引擎比较
开源工作流引擎是一种用于管理和自动化业务流程的软件它可以帮助用户实现业务流程的可视化设计、流程编排、任务调度、监控和优化等功能。本文将介绍几种常见的开源工作流引擎并进行比较。目前市场上比较主流的开源流程引擎有Activiti、Camunda、Flowable。
1.1、Activiti
Activiti是一个轻量级的开源工作流引擎采用Java语言开发基于BPMN 2.0规范支持嵌入式部署和分布式部署。Activiti提供了丰富的API和插件支持与Java应用程序进行集成。它还提供了Web界面和REST API可以方便地进行流程设计、部署、调度和监控。Activiti具有以下优点
易用性和灵活性Activiti提供了简单易用的流程设计器和API支持多种流程模型和任务类型可以满足不同场景和需求的使用。可伸缩性和性能Activiti支持嵌入式和分布式部署可以扩展集群规模以支持更大的业务流程和更高的并发量。此外它还提供了优化和缓存机制可以提高性能和响应速度。社区支持和生态系统Activiti拥有庞大的社区和活跃的开发者提供了丰富的插件和工具可以扩展其功能和使用。例如Activiti Explorer可以用于流程设计和管理Camunda Modeler可以用于编辑BPMN模型Flowable Task可以用于任务管理等。安全性和可靠性Activiti提供了可靠的安全性控制可以对数据进行访问控制和加密以满足不同场景和需求的安全要求。它还提供了事务管理和错误处理机制可以保证业务流程的可靠性和稳定性。
1.2、Camunda
Camunda是一个强大的开源工作流引擎采用Java语言开发支持BPMN 2.0规范和CMMN规范。Camunda提供了丰富的API和插件支持与Java应用程序进行集成。它还提供了Web界面和REST API可以方便地进行流程设计、部署、调度和监控。Camunda具有以下优点
功能丰富和灵活性Camunda提供了丰富的功能和灵活的流程设计支持多种流程模型和任务类型可以满足不同场景和需求的使用。可伸缩性和性能Camunda支持嵌入式和分布式部署可以扩展集群规模以支持更大的业务流程和更高的并发量。此外它还提供了优化和缓存机制可以提高性能和响应速度。社区支持和生态系统Camunda拥有庞大的社区和活跃的开发者提供了丰富的插件和工具可以扩展其功能和使用。例如Camunda Modeler可以用于编辑BPMN模型Camunda Cockpit可以用于任务管理和流程监控Camunda Tasklist可以用于任务列表等。可扩展的架构和APICamunda采用可扩展的架构和API可以方便地进行集成和扩展。例如它支持自定义流程引擎插件、外部任务处理器、表单引擎等。安全性和可靠性Camunda提供了可靠的安全性控制可以对数据进行访问控制和加密以满足不同场景和需求的安全要求。它还提供了事务管理和错误处理机制可以保证业务流程的可靠性和稳定性。
1.3、Flowable
Flowable是一个开源的轻量级工作流引擎基于Activiti 5.x版本开发支持BPMN 2.0规范和CMMN规范。Flowable提供了丰富的API和插件支持与Java应用程序进行集成。它还提供了Web界面和REST API可以方便地进行流程设计、部署、调度和监控。Flowable具有以下优点
易用性和灵活性Flowable提供了简单易用的流程设计器和API支持多种流程模型和任务类型可以满足不同场景和需求的使用。可伸缩性和性能Flowable支持嵌入式和分布式部署可以扩展集群规模以支持更大的业务流程和更高的并发量。此外它还提供了优化和缓存机制可以提高性能和响应速度。社区支持和生态系统Flowable拥有庞大的社区和活跃的开发者提供了丰富的插件和工具可以扩展其功能和使用。例如Flowable Modeler可以用于流程设计和管理Flowable Task可以用于任务管理和流程监控Flowable Admin可以用于集群管理等。可扩展的架构和APIFlowable采用可扩展的架构和API可以方便地进行集成和扩展。例如它支持自定义流程引擎插件、外部任务处理器、表单引擎等。安全性和可靠性Flowable提供了可靠的安全性控制可以对数据进行访问控制和加密以满足不同场景和需求的安全要求。它还提供了事务管理和错误处理机制可以保证业务流程的可靠性和稳定性。
2、flowable安装
2.1、下载软件
Github链接目前flowable已经更新到Flowable 7.0.0.M2版本了。 安装方式有很多可以通过下载zip包也可以通过docker拉取镜像进行部署本文采用zip的window环境部署。
下载安装包我下载的是flowable-6.7.0版本同时需要配合tomcat选择的是apache-tomcat-9.0.79版本服务进行部署tomcat下载地址 下载上面两个软件之后还需要配置flowale的配置数据存储我选择的mysql数据库当然他还支持其他数据库类型。mysql数据库是docker镜像运行的这里不再赘述安装过程可以看我往期docker mysql安装.
2.2、解压运行
分别解压tomcat和flowable 把flowable-6.7.0\wars目录下的flowable-ui.war拷贝到apache-tomcat-9.0.79\webapps下面启动tomcat startup.bat
此时会解压war文件同时会删除war文件同时会生成新文件apache-tomcat-9.0.79\webapps\flowable-ui.
2.3、配置数据源 修改apache-tomcat-9.0.79\webapps\flowable-ui\WEB-INF\classes\flowable-default.properties 参考
server.port8080
server.servlet.context-path/flowable-ui
spring.jmx.unique-namestrue
# This is needed to force use of JDK proxies instead of using CGLIB
spring.aop.proxy-target-classfalse
spring.aop.autofalse
spring.application.nameflowable-ui
spring.banner.locationclasspath:/org/flowable/spring/boot/flowable-banner.txt
# The default domain for generating ObjectNames must be specified. Otherwise when multiple Spring Boot applications start in the same servlet container
# all would be created with the same name (com.zaxxer.hikari:namedataSource,typeHikariDataSource) for example
spring.jmx.default-domain${spring.application.name}
#
# SECURITY
#
spring.security.filter.dispatcher-typesREQUEST,FORWARD,ASYNC# Expose all actuator endpoints to the web
# They are exposed, but only authenticated users can see /info and /health abd users with access-admin can see the others
management.endpoints.web.exposure.include*
# Full health details should only be displayed when a user is authorized
management.endpoint.health.show-detailswhen_authorized
# Only users with role access-admin can access full health details
management.endpoint.health.rolesaccess-admin
# Spring prefixes the roles with ROLE_. However, Flowable does not have that concept yet, so we need to override that with an empty string
flowable.common.app.role-prefix#
# SECURITY OAuth2
# Examples are for Keycloak
#
#spring.security.oauth2.resourceserver.jwt.issuer-urikeycloakLocation/auth/realms/realmName
#spring.security.oauth2.client.registration.keycloak.client-idclientId
#spring.security.oauth2.client.registration.keycloak.client-secretclientSecret
#spring.security.oauth2.client.registration.keycloak.client-nameFlowable UI Keycloak
#spring.security.oauth2.client.registration.keycloak.authorization-grant-typeauthorization_code
#spring.security.oauth2.client.provider.keycloak.issuer-urikeycloakLocation/auth/realms/realmName
#spring.security.oauth2.client.provider.keycloak.user-name-attributepreferred_username#flowable.common.app.security.typeoauth2
#flowable.common.app.security.oauth2.authorities-attributegroups
#flowable.common.app.security.oauth2.groups-attributeuserGroups
#flowable.common.app.security.oauth2.default-authoritiesaccess-task
#flowable.common.app.security.oauth2.default-groupsflowableUser
#flowable.common.app.security.oauth2.full-name-attributename
#flowable.common.app.security.oauth2.email-attributeemail#
# DATABASE
##spring.datasource.driver-class-nameorg.h2.Driver
#spring.datasource.urljdbc:h2:~/flowable-db/engine-db;AUTO_SERVERTRUE;AUTO_SERVER_PORT9093;DB_CLOSE_DELAY-1spring.datasource.driver-class-namecom.mysql.jdbc.Driver
spring.datasource.urljdbc:mysql://192.168.56.100:13306/flowable?characterEncodingUTF-8#spring.datasource.driver-class-nameorg.postgresql.Driver
#spring.datasource.urljdbc:postgresql://localhost:5432/flowable#spring.datasource.driver-class-namecom.microsoft.sqlserver.jdbc.SQLServerDriver
#spring.datasource.urljdbc:sqlserver://localhost:1433;databaseNameflowablea#spring.datasource.driver-class-nameoracle.jdbc.driver.OracleDriver
#spring.datasource.urljdbc:oracle:thin:localhost:1521:FLOWABLE#spring.datasource.driver-class-namecom.ibm.db2.jcc.DB2Driver
#spring.datasource.urljdbc:db2://localhost:50000/flowablespring.datasource.usernameroot
spring.datasource.passwordmy-secret-pw# JNDI CONFIG# If uncommented, the datasource will be looked up using the configured JNDI name.
# This will have preference over any datasource configuration done below that doesnt use JNDI
#
# Eg for JBoss: java:jboss/datasources/flowableDS
#
#spring.datasource.jndi-namejdbc/flowableDS# Set whether the lookup occurs in a J2EE container, i.e. if the prefix java:comp/env/ needs to be added if the JNDI
# name doesnt already contain it. Default is true.
#datasource.jndi.resourceReftrue#
# Connection pool (see https://github.com/brettwooldridge/HikariCP#configuration-knobs-baby)
#spring.datasource.hikari.poolName${spring.application.name}
# 10 minutes
spring.datasource.hikari.maxLifetime600000
# 5 minutes
spring.datasource.hikari.idleTimeout300000
spring.datasource.hikari.minimumIdle10
spring.datasource.hikari.maximumPoolSize50
# test query for H2, MySQL, PostgreSQL and Microsoft SQL Server
#spring.datasource.hikari.connection-test-queryselect 1
# test query for Oracle
#spring.datasource.hikari.connection-test-querySELECT 1 FROM DUAL
# test query for DB2
#spring.datasource.hikari.connection-test-querySELECT current date FROM sysibm.sysdummy1#
# Default Task Executor (will be used for Async)
#
spring.task.execution.pool.core-size2
spring.task.execution.pool.max-size50
spring.task.execution.pool.queue-capacity10000
spring.task.execution.thread-name-prefixflowable-ui-task-Executor-#
# Task scheduling
#
spring.task.scheduling.pool.size5#
# EMAIL
##flowable.mail.server.hostlocalhost
#flowable.mail.server.port1025
#flowable.mail.server.username
#flowable.mail.server.password#
# FLOWABLE
#flowable.process.definition-cache-limit512
#flowable.dmn.strict-modefalse
flowable.process.async.executor.default-async-job-acquire-wait-timePT5S
flowable.process.async.executor.default-timer-job-acquire-wait-timePT5Sflowable.cmmn.async.executor.default-async-job-acquire-wait-timePT5S
flowable.cmmn.async.executor.default-timer-job-acquire-wait-timePT5S# The maximum file upload limit. Set to -1 to set to no limit. Expressed in bytes
spring.servlet.multipart.max-file-size10MB
# The maximum request size limit. Set to -1 to set to no limit.
# When multiple files can be uploaded this needs to be more than the max-file-size.
spring.servlet.multipart.max-request-size10MB# For development purposes, data folder is created inside the sources ./data folder
flowable.content.storage.root-folderdata/
flowable.content.storage.create-roottrueflowable.common.app.idm-admin.useradmin
flowable.common.app.idm-admin.passwordtestflowable.experimental.debugger.enabledfalse# Rest API in task application# If false, disables the rest api in the task app
flowable.task.app.rest-enabledtrue# Configures the way user credentials are verified when doing a REST API call:
# any-user : the user needs to exist and the password need to match. Any user is allowed to do the call (this is the pre 6.3.0 behavior)
# verify-privilege : the user needs to exist, the password needs to match and the user needs to have the rest-api privilege
# If nothing set, defaults to verify-privilege
flowable.rest.app.authentication-modeverify-privilege# Enable form field validation after form submission on the engine side
flowable.form-field-validation-enabledfalse# Flowable Admin Properties# Passwords for rest endpoints and master configs are stored encrypted in the database using AES/CBC/PKCS5PADDING
# It needs a 128-bit initialization vector (http://en.wikipedia.org/wiki/Initialization_vector)
# and a 128-bit secret key represented as 16 ascii characters below
#
# Do note that if these properties are changed after passwords have been saved, all existing passwords
# will not be able to be decrypted and the password would need to be reset in the UI.
flowable.admin.app.security.encryption.credentials-i-v-specj8kdO2hejA9lKmm6
flowable.admin.app.security.encryption.credentials-secret-spec9FGl73ngxcOoJvmL
#flowable.admin.app.security.preemptive-basic-authenticationtrue# Flowable IDM Properties#
# LDAP
#
#flowable.idm.ldap.enabledtrue
#flowable.idm.ldap.serverldap://localhost
#flowable.idm.ldap.port10389
#flowable.idm.ldap.useruidadmin, ousystem
#flowable.idm.ldap.passwordsecret
#flowable.idm.ldap.base-dnoflowable
#flowable.idm.ldap.query.user-by-id((objectClassinetOrgPerson)(uid{0}))
#flowable.idm.ldap.query.user-by-full-name-like((objectClassinetOrgPerson)(|({0}*{1}*)({2}*{3}*)))
#flowable.idm.ldap.query.all-users(objectClassinetOrgPerson)
#flowable.idm.ldap.query.groups-for-user((objectClassgroupOfUniqueNames)(uniqueMember{0}))
#flowable.idm.ldap.query.all-groups(objectClassgroupOfUniqueNames)
#flowable.idm.ldap.query.group-by-id((objectClassgroupOfUniqueNames)(uniqueId{0}))
#flowable.idm.ldap.attribute.user-iduid
#flowable.idm.ldap.attribute.first-namecn
#flowable.idm.ldap.attribute.last-namesn
#flowable.idm.ldap.attribute.emailmail
#flowable.idm.ldap.attribute.group-idcn
#flowable.idm.ldap.attribute.group-namecn
#flowable.idm.ldap.cache.group-size10000
#flowable.idm.ldap.cache.group-expiration180000#
# Keycloak
#
#flowable.idm.app.keycloak.enabledtrue
#flowable.idm.app.keycloak.serverkeycloakLocation
#flowable.idm.app.keycloak.authentication-realmmaster
#flowable.idm.app.keycloak.authentication-useradmin
#flowable.idm.app.keycloak.authentication-passwordadmin
#flowable.idm.app.keycloak.realmrealm#
# DEFAULT ADMINISTRATOR ACCOUNT
#flowable.idm.app.admin.user-idadmin
flowable.idm.app.admin.passwordtest
flowable.idm.app.admin.first-nameTest
flowable.idm.app.admin.last-nameAdministrator
flowable.idm.app.admin.emailtest-adminexample-domain.tld# Enable and configure JMS
#flowable.task.app.jms-enabledtrue
#spring.activemq.broker-urltcp://localhost:61616# Enable and configure RabbitMQ
#flowable.task.app.rabbit-enabledtrue
#spring.rabbitmq.addresseslocalhost:5672
#spring.rabbitmq.usernameguest
#spring.rabbitmq.passwordguest# Enable and configure Kafka
#flowable.task.app.kafka-enabledtrue
#spring.kafka.bootstrap-serverslocalhost:9092默认情况下flowable有没有把mysql驱动程序打入到war包里面需要手动添加对应的驱动。apache-tomcat-9.0.79\webapps\flowable-ui\WEB-INF\lib 我选择的是mysql-connector-java-5.1.45.jar驱动具体可以从网上下载也可以通过maven方式从中央仓库拉取。 再次启动tomcat访问http://127.0.0.1:8080/flowable-ui 初始用户名和密码admin/test
3、springboot接入flowable
登录flowable之后选择建模器应用程序添加一个流程我这边已经添加了一个简单的请假流程。 新入门可以导入我们流程定义具体文件在看的我资源。重点介绍springboot如何集成flowable配置后续有机会在单独介绍里程配置说明。
新建springboot项目添加响应的依赖。 dependenciesdependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependencydependencygroupIdorg.flowable/groupIdartifactIdflowable-spring-boot-starter/artifactIdversion6.7.0/version/dependencydependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion5.1.45/version/dependency!-- Flowable 内部日志采用 SLF4J --dependencygroupIdorg.slf4j/groupIdartifactIdslf4j-api/artifactIdversion1.7.21/version/dependencydependencygroupIdorg.slf4j/groupIdartifactIdslf4j-log4j12/artifactIdversion1.7.21/version/dependency/dependencies application.yml配置
spring:datasource:url: jdbc:mysql://192.168.56.100:13306/flowable?useSSLfalsecharacterEncodingUTF-8serverTimezoneGMT%2B8driver-class-name: com.mysql.jdbc.Driverusername: rootpassword: my-secret-pw
# flowable 配置
flowable:# 关闭异步不关闭历史数据的插入就是异步的会在同一个事物里面无法回滚# 开发可开启会提高些效率上线需要关闭async-executor-activate: false
server:port: 18080
Controller
import liquibase.pro.packaged.O;
import liquibase.pro.packaged.U;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.engine.*;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.runtime.ActivityInstance;
import org.flowable.engine.runtime.Execution;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.image.ProcessDiagramGenerator;
import org.flowable.task.api.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;/*** author pyj* date 2019/10/30*/
RestController
RequestMapping(flowable)
public class TestController {Autowiredprivate RuntimeService runtimeService;Autowiredprivate TaskService taskService;Autowiredprivate HistoryService historyService;Autowiredprivate RepositoryService repositoryService;Autowiredprivate ProcessEngine processEngine;/*** 创建流程** param userId* param days* param reason* return*/GetMapping(add)public String addExpense(String userId, String days, String reason) {MapString, Object map new HashMap();map.put(employee, userId);map.put(nrOfHolidays, days);map.put(description, reason);ProcessInstance processInstance runtimeService.startProcessInstanceByKey(holidayRequest, map);return 提交成功,流程ID为 processInstance.getId();}/*** 获取指定用户组流程任务列表** return*/GetMapping(listtask)public Object listtask() {StringBuffer btf new StringBuffer();ListTask list taskService.createTaskQuery().list();for (Task task : list){btf.append(task.getId()\r\n);System.out.println(task.getId());}return btf.toString();}/*** 获取指定用户组流程任务列表** param group* return*/GetMapping(list)public Object list(String group) {ListTask list taskService.createTaskQuery().list();ListTask tasks taskService.createTaskQuery().taskCandidateGroup(group).list();return tasks.toString();}/*** 通过/拒绝任务** param taskId* param approved 1 true 2false* return*/GetMapping(apply)public String apply(String taskId, String approved) {Task task taskService.createTaskQuery().taskId(taskId).singleResult();if (task null) {return 流程不存在;}MapString, Object variables new HashMap();Boolean apply approved.equals(1) ? true : false;variables.put(approved, apply);taskService.complete(taskId, variables);return 审批是否通过 approved;}/*** 查看历史流程记录** param processInstanceId* return*/GetMapping(historyList)public Object getHistoryList(String processInstanceId) {ListHistoricActivityInstance historicActivityInstances historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstanceId).finished().orderByHistoricActivityInstanceEndTime().asc().list();return historicActivityInstances;}/*** 驳回流程实例** param taskId* param targetTaskKey* return*/GetMapping(rollbask)public String rollbaskTask(String taskId, String targetTaskKey) {Task currentTask taskService.createTaskQuery().taskId(taskId).singleResult();if (currentTask null) {return 节点不存在;}ListString key new ArrayList();key.add(currentTask.getTaskDefinitionKey());runtimeService.createChangeActivityStateBuilder().processInstanceId(currentTask.getProcessInstanceId()).moveActivityIdsToSingleActivityId(key, targetTaskKey).changeState();return 驳回成功...;}/*** 终止流程实例** param processInstanceId*/public String deleteProcessInstanceById(String processInstanceId) {// 这个参数本来可以写删除原因runtimeService.deleteProcessInstance(processInstanceId, );return 终止流程实例成功;}/*** 挂起流程实例** param processInstanceId 当前流程实例id*/GetMapping(hangUp)public String handUpProcessInstance(String processInstanceId) {runtimeService.suspendProcessInstanceById(processInstanceId);return 挂起流程成功...;}/*** 恢复唤醒被挂起的流程实例** param processInstanceId 流程实例id*/GetMapping(recovery)public String activateProcessInstance(String processInstanceId) {runtimeService.activateProcessInstanceById(processInstanceId);return 恢复流程成功...;}/*** 判断传入流程实例在运行中是否存在** param processInstanceId* return*/GetMapping(isExist/running)public Boolean isExistProcIntRunning(String processInstanceId) {ProcessInstance processInstance runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();if (processInstance null) {return false;}return true;}/*** 判断流程实例在历史记录中是否存在* param processInstanceId* return*/GetMapping(isExist/history)public Boolean isExistProcInHistory(String processInstanceId) {HistoricProcessInstance historicProcessInstance historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();if (historicProcessInstance null) {return false;}return true;}/*** 我发起的流程实例列表** param userId* return 流程实例列表*/GetMapping(myTasks)public ListHistoricProcessInstance getMyStartProcint(String userId) {ListHistoricProcessInstance list historyService.createHistoricProcessInstanceQuery().startedBy(userId).orderByProcessInstanceStartTime().asc().list();return list;}/*** 查询流程图** param httpServletResponse* param processId* throws Exception*/RequestMapping(value processDiagram)public void genProcessDiagram(HttpServletResponse httpServletResponse, String processId) throws Exception {ListActivityInstance activityInstanceList runtimeService.createActivityInstanceQuery().list();for(ActivityInstance activityInstance : activityInstanceList){System.out.println(activityInstance.getId());}System.out.println();ListProcessInstance list runtimeService.createProcessInstanceQuery().list();for(ProcessInstance processInstance : list){System.out.println(processInstance.getId());}ProcessInstance pi runtimeService.createProcessInstanceQuery().processInstanceId(processId).singleResult();//流程走完的不显示图if (pi null) {return;}Task task taskService.createTaskQuery().processInstanceId(pi.getId()).singleResult();//使用流程实例ID查询正在执行的执行对象表返回流程实例对象String InstanceId task.getProcessInstanceId();ListExecution executions runtimeService.createExecutionQuery().processInstanceId(InstanceId).list();//得到正在执行的Activity的IdListString activityIds new ArrayList();ListString flows new ArrayList();for (Execution exe : executions) {ListString ids runtimeService.getActiveActivityIds(exe.getId());activityIds.addAll(ids);}//获取流程图BpmnModel bpmnModel repositoryService.getBpmnModel(pi.getProcessDefinitionId());ProcessEngineConfiguration engconf processEngine.getProcessEngineConfiguration();ProcessDiagramGenerator diagramGenerator engconf.getProcessDiagramGenerator();InputStream in diagramGenerator.generateDiagram(bpmnModel, png, activityIds, flows, engconf.getActivityFontName(), engconf.getLabelFontName(), engconf.getAnnotationFontName(), engconf.getClassLoader(), 1.0,true);OutputStream out null;byte[] buf new byte[1024];int legth 0;try {out httpServletResponse.getOutputStream();while ((legth in.read(buf)) ! -1) {out.write(buf, 0, legth);}} finally {if (in ! null) {in.close();}if (out ! null) {out.close();}}}}Flowable提供了几个Service接口和实现类可以通过service拿到流程的一些定义、流转等信息。
正如TestController里面定义的几个方法分别是实例化流程审批流程查看流程等操作。如下
实例化流程 审批流程 拉取当前流程任务清单 查看流程状态 具体大家可以参考如下文章有详细的springboot集成指引。
Flowable BPMN 用户手册 (v 6.3.0)