Flowable是19年基于activity开出的分支,大多业务场景只是使用activity走线上请假审核流程,实际上大厂里对flowable的使用更多是高并发状态下流程化、模板化功能开发。
一、概念
1、先贴6.4.x的中文版用户手册
https://jeesite.gitee.io/front/flowable/6.4.2/bpmn/index.html
2、Flowable是一个使用Java编写的轻量级业务流程引擎。
这就给Flowable更好的结合现在java微服务生态提供了可能。
二、集成开发
1、cse集成flowable
上文说到flowable是由java编写的,那么集成在spring、springboot、serviceCobm都是非常轻松的。
这里以serviceCobm为例展示,集成spring的案例官网就有,自不必多多说。
1.1引cse框架包
<dependencyManagement>
<dependencies>
<!--cse-->
<dependency>
<groupId>org.apache.servicecomb</groupId>
<artifactId>java-chassis-dependencies</artifactId>
<version>${servicecomb.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
1.2 引入flowable6.x.x 最新版已经到了6.6.0,查看了官网的升级介绍,对其中部分API做了更新,但大部分逻辑没有发生改变。
<!--flowable start-->
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-engine</artifactId>
<version>6.4.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.flowable/flowable-spring -->
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-spring</artifactId>
<version>6.4.0</version>
</dependency>
<dependency>
<groupId>com.fasterxml.uuid</groupId>
<artifactId>java-uuid-generator</artifactId>
<version>3.1.3</version>
</dependency>
<!--flowable end-->
三、配置流程引擎及服务引擎
配置流程引擎,有2中方式。
3.1 代码配置流程引擎
import lombok.Data;
import org.flowable.engine.*;
import org.flowable.engine.impl.cfg.StandaloneProcessEngineConfiguration;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
/**
* 功能说明
*
* @author asky
* @date 2021/7/18 0018 7:22
*/
@Configuration
@ConfigurationProperties(prefix = "spring.datasource")
@Data
class ProcessEngineConfig {
@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() {
// 流程引擎配置
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);
} catch (Exception e) {
e.printStackTrace();
}
// 初始化流程引擎对象
ProcessEngine processEngine = cfg.buildProcessEngine();
return processEngine;
}
@Bean
public RepositoryService getRepositoryService(){
return initProcessEngine().getRepositoryService();
}
@Bean
public RuntimeService getRuntimeService(){
return initProcessEngine().getRuntimeService();
}
@Bean
public HistoryService getHistoryService(){
return initProcessEngine().getHistoryService();
}
@Bean
public TaskService getTaskService(){
return initProcessEngine().getTaskService();
}
}
和代码对应的要在配置文件中加上:
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/flowable
driverClassName: com.mysql.jdbc.Driver
username: root
password: root
3.2 配置文件注入引擎
该方式在官网中已提供样例,适配多种数据库,这里直接用mysql。(值得注意的是flowable引擎的初始化会扫描classpath下的flowable.cfg.xml来构建,但通过spring的依赖注入也是可以的)
注意:cse框架扫描bean需要制定为 classpath*:META-INF/spring/*.bean.xml,搞错了会导致注入失败。
特别需要注意的是:asyncExecutorActivate,这个是设置异步工作流开关,需要置为true,否则后续的java代理类默认关闭,或找不到相关bean。
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<!--数据源-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" >
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://127.0.0.1:3306/flowable" />
<property name="username" value="root" />
<property name="password" value="root" />
<property name="defaultAutoCommit" value="true" />
</bean>
<!--事务管理器-->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
<bean id="processEngineConfiguration" class="org.flowable.spring.SpringProcessEngineConfiguration">
<property name="dataSource" ref="dataSource" />
<property name="transactionManager" ref="transactionManager" />
<property name="databaseSchemaUpdate" value="true" />
<property name="asyncExecutorActivate" value="true" />
<property name="idGenerator">
<bean class="com.asky.content.manager.flowable.UuidGenerate" />
</property>
</bean>
<!--流程引擎-->
<bean id="processEngine" class="org.flowable.spring.ProcessEngineFactoryBean">
<property name="processEngineConfiguration" ref="processEngineConfiguration" />
</bean>
<!--flowable服务引擎-->
<bean id="repositoryService" factory-bean="processEngine" factory-method="getRepositoryService" />
<bean id="runtimeService" factory-bean="processEngine" factory-method="getRuntimeService" />
<bean id="taskService" factory-bean="processEngine" factory-method="getTaskService" />
<bean id="historyService" factory-bean="processEngine" factory-method="getHistoryService" />
<bean id="managementService" factory-bean="processEngine" factory-method="getManagementService" />
</beans>
注意:这里的数据库依赖要导包
<!-- https://mvnrepository.com/artifact/commons-dbcp/commons-dbcp -->
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
上述2种方式都可以完成服务引擎的初始化构建。
四、流程部署、查询和启动
@Autowired
public ProcessEngine processEngine;
public void startFlowableTest(){
//部署流程定义
Deployment deployment = processEngine.getRepositoryService().createDeployment()
.tenantId("abc")
.addClasspathResource("helloWorld.bpmn20.xml")
.deploy();
//API查询引擎
ProcessDefinition processDefinition = processEngine.getRepositoryService().createProcessDefinitionQuery()
.deploymentId(deployment.getId())
.singleResult();
System.out.println("Found process definition : " + processDefinition.getName());
//启动流程
ProcessInstance processInstance = processEngine.getRuntimeService().startProcessInstanceByKeyAndTenantId(
processDefinition.getKey(), processDefinition.getKey(),null,"abc");
//使用历史数据
HistoryService historyService = processEngine.getHistoryService();
List<HistoricActivityInstance> activities =
historyService.createHistoricActivityInstanceQuery()
.processInstanceId(processInstance.getId())
.finished()
.orderByHistoricActivityInstanceEndTime().asc()
.list();
}
五、实现JavaDelegate
如官网8.5.3章节所示,4种方式来实现java逻辑的调用。
5.1 flowable:class属性提供全限定类名
该种方式是最简单轻便的,在画流程图时,指定Id即流程处理器service task的名称,此时指定class,会在流程进入到当前步骤时,找到对应的类,并执行其execute方法。
public class MyJavaDelegate implements JavaDelegate {
public void execute(DelegateExecution execution) {
String var = (String) execution.getVariable("input");
var = var.toUpperCase();
execution.setVariable("input", var);
//anyother service code
}
}
5.2 bean对象的执行
此时,delegateExpressionBean同样需要实现JavaDelegate方法,所以当进入到serviceTask时,都会由delegateExpressionBean进行调度。
6、其他
处理器的uuid生产等,可见:
https://jeesite.gitee.io/front/flowable/6.4.2/bpmn/index.html#advanced.uuid.generator