Flowable
默认的部署默认情况下,我们放在 resources/processes
目录下的所有流程文件会自动被部署,流程文件的后缀有两种形式 bpmn20.xml
或者 bpmn
。当然,无论是存放流程文件的位置,还是流程文件的格式,都是可以定制的,涉及到的属性主要有三个,可在 application.properties
中进行配置
flowable.check-process-definitions=false
flowable.process-definition-location-prefix=classpath*:/processes/
flowable.process-definition-location-suffixes=**.bpmn20.xml,**.bpmn
flowable.check-process-definitions
:表示在项目启动的时候,去检查文件目录是否有对应的流程文件,默认值为 true
表示如果有流程文件就自动部署,false
表示不检查,那么也就不会自动部署flowable.process-definition-location-prefix
:这个是流程文件的位置,默认就是 classpath*:/processes/
,当然开发者也可以进行配置flowable.process-definition-location-suffixes
:这个是流程文件的后缀,默认有两个,分别是 **.bpmn20.xml 和 **.bpmn
,当然开发者也可以进行配置Flowable
的动态部署有的时候,我们的流程可能并不是提前设计好的,而是项目启动之后,动态部署的,例如项目启动成功之后,动态上传一个流程的 XML
文件进行部署,这也是一种比较常见的场景,对于这种情况,我们可以按照如下方式进行部署
@RestController
public class ProcessDeployController {
@Autowired
RepositoryService repositoryService;
@PostMapping("/deploy")
public RespBean deploy(MultipartFile file) throws IOException {
DeploymentBuilder deploymentBuilder = repositoryService.createDeployment()
.category("javaboy的工作流分类")
.name("javaboy的工作流名称")
.addInputStream(file.getOriginalFilename(), file.getInputStream())
.key("javaboy的工作流key");
Deployment deployment = deploymentBuilder.deploy();
return RespBean.ok("部署成功",deployment.getId());
}
}
addInputStream
,通过该方法去指定流程文件。官方提供的指定流程文件的方式有好几种;除了 addInputStream
之外,另外还有一个 addString
,这个就是将流程文件转为一个字符串传入进来;addBytes
是将流程文件转为字节数组传进来;addClasspathResource
方法则是直接从 classpath
目录下去加载流程文件,这几个方法根据自己的使用场景选择一个合适的方法去调用即可addInputStream/addBytes/addString
等方法都需要设置资源名,这个名称是可以随意设置的,但是注意名称的后缀,需要是 bpmn20.xml
或者 bpmn
,否则流程没有部署SpringBoot
整合 Flowable
关于 Flowable
版本与 SpringBoot
版本对应关系请查看:https://blog.csdn.net/JinYJ2014/article/details/121530632
<dependency>
<groupId>org.flowablegroupId>
<artifactId>flowable-spring-boot-starterartifactId>
<version>6.4.1version>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.38version>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druid-spring-boot-starterartifactId>
<version>1.1.10version>
dependency>
server.port=8080
#JDBC 配置:MySQL Server 版本为 5.7.39
spring.datasource.druid.url=jdbc:mysql://127.0.0.1:3306/flowable1?characterEncoding=utf8&useSSL=false&autoReconnect=true&serverTimezone=UTC
spring.datasource.druid.username=root
spring.datasource.druid.password=123456
spring.datasource.druid.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
#druid 连接池配置
spring.datasource.druid.initial-size=3
spring.datasource.druid.min-idle=3
spring.datasource.druid.max-active=10
spring.datasource.druid.max-wait=60000
#关闭定时任务JOB
flowable.async-executor-activate=false
#当Flowable发现库与数据库表结构不一致时,会自动将数据库表结构升级至新版本
flowable.database-schema-update=true
#在项目启动时,去检查文件目录是否有对应的流程文件,默认值为 true 表示如果有流程文件就自动部署,false 表示不检查,那么也就不会自动部署
flowable.check-process-definitions=true
#指定工作流程图的位置,默认值
flowable.process-definition-location-prefix=classpath*:/processes/
#指定工作流程图文件的后缀,默认值
flowable.process-definition-location-suffixes=**.bpmn20.xml, **.bpmn
#打印 SQL 语句
logging.level.org.flowable.engine.impl.persistence.entity.*=debug
logging.level.org.flowable.task.service.impl.persistence.entity.*=debug
系统启动的时候检查如果数据库对应的表结构没有创建,会帮助我们先创建对应的表结构。到此整合就搞定了,非常的简单,然后我们就可以通过案例来测试了
使用 Flowable
默认的部署的方式,即将工作流程图文件放在 resources/processes
目录下,这样它会被自动部署
我们可以从容器中直接获取相关的对象,ProcessEngine,RuntimeService
等
@SpringBootTest
@RunWith(value = SpringRunner.class)
public class AppTest {
@Autowired
private RepositoryService repositoryService;
@Test
public void shouldAnswerWithTrue() {
// ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// RepositoryService repositoryService = processEngine.getRepositoryService();
Deployment deploy = repositoryService.createDeployment()
.addClasspathResource("processes/MyLeaveProcessOne.bpmn20.xml")
.name("员工请假流程")
.category("请假")// 分类
.tenantId("user1Id")// 租户id
.deploy();
System.out.println("deploy.getId() = " + deploy.getId());
System.out.println("deploy.getName() = " + deploy.getName());
System.out.println("deploy.getCategory() = " + deploy.getCategory());
}
}
运行结果,说明流程部署成功
流程部署完毕之后,会得到这 70
张表,Flowable
版本是 6.4.1
在我们的流程部署过程中,一共有三张表参与到我们的工作中了
act_re_deployment
表这个表是流程部署表,每部署一个流程,这张表中就会新增一条记录,用来描述我们刚刚定义好的流程
这里的 ID_、NAME_、CATEGORY_
等等,就是我们在部署流程的时候设置的参数
字段 | 名称 | 备注 |
---|---|---|
ID_ | 主键 | |
NAME_ | 名称 | |
CATEGORY_ | 分类 | |
TENANT_ID_ | 租户ID | |
DEPLOY_TIME_ | 部署时间 | |
DERIVED_FROM_ | 来源于 | |
DERIVED_FROM_ROOT_ | 来源于 | |
ENGINE_VERSION_ | 流程引擎的版本 |
act_re_procdef
表这是流程定义表,我们每定义的一个流程,都会记录在这张表中
DEPLOYMENT_ID
字段和 act_re_deployment
表进行了关联,所以 act_re_deployment
和 act_re_procdef
表的关系,其实是一对一的关系,部署表中的一条记录对应流程定义表中的一条记录CATEGORY_
的字段,这个字段表示流程的分类,注意这个和部署的分类可不一样,流程的分类,说白了其实就是我们流程定义 XML
文件中的 targetNamespace
属性VERSION_
字段,这个看名字就知道是描述记录的版本号,当我们修改了流程的内容之后,重新部署的时候,act_re_deployment
和 act_re_procdef
表均会自动增加一条记录数;其中流程定义表 act_re_procdef
中的记录的 VERSION_
字段的值会自动加 1
,这样我们就能够看到不同历史版本的流程定义字段 | 名称 | 备注 |
---|---|---|
ID_ | 主键 | |
REV_ | 版本号 | |
CATEGORY_ | 分类 | 流程定义的Namespace就是类别 |
NAME_ | 名称 | |
KEY_ | 标识 | |
VERSION_ | 版本 | |
DEPLOYMENT_ID_ | 部署ID | |
RESOURCE_NAME_ | 资源名称 | 流程bpmn文件名称 |
DGRM_RESOURCE_NAME_ | 图片资源名称 | |
DESCRIPTION_ | 描述 | |
HAS_START_FORM_KEY_ | 拥有开始表单标识 | start节点是否存在formKey 0否 1是 |
HAS_GRAPHICAL_NOTATION_ | 拥有图形信息 | |
SUSPENSION_STATE_ | 挂起状态 | 暂停状态 1激活 2暂停 |
TENANT_ID_ | 租户ID | |
act_ge_bytearray
表涉及到的第三张表是这个通用数据存储表,这个表的字段比较少
这个表中有一个 DEPLOYMENT_ID
字段,这个就是跟 act_re_deployment
表关联的字段,一条流程部署记录在 act_ge_bytearray
表中对应两条记录,分别是记录 XML
文件和记录流程图片
这个表中有一个 BYTES_
字段,我们部署的流程的 XML
文件就保存在这里,同时,系统默认还会根据 XML
文件生成一张流程图片,也保存在这里
字段 | 名称 | 备注 |
---|---|---|
ID_ | 主键 | |
REV_ | 版本号 | |
NAME_ | 名称 | 部署的文件名称,如:holiday-request-new.bpmn20.xml、holiday-request-new.bpmn20.png |
DEPLOYMENT_ID_ | 部署ID | |
BYTES_ | 字节(二进制数据) | |
GENERATED_ | 是否系统生成 | 0为用户上传, 1为系统自动生成, 比如系统会 自动根据xml生 成png |