这里写自定义目录标题
flowable学习笔记
第一章 整体流程
业务流程主要分以下步骤:
第二章 自定义表单
推荐使用form-create
具体怎么集成看官网,如何与后端组合后面有时间再写
第三章 flowable常用类
引擎
#### 引擎服务类信息
AbstractEngineConfiguration:引擎顶级父类
CmmnEngineConfiguration
IdmEngineConfiguration
AppEngineConfiguration
ProcessEngineConfiguration
ProcessEngines:流程引擎管理类
ProcessEngine:流程引擎类
ProcessEngineImpl:流程引擎实现类
ProcessEngineConfiguration:流程引擎配置类
ProcessEngineConfigurationImpl:流程引擎配置实现类
EngineInfo:流程引擎信息类
常用服务类信息
ProcessEngine 流程引擎类
RepositoryService 流程定义
DynamicBpmnService 动态bpmn服务
HistoryService 历史
FormService 表单
TaskService 任务
IdentityService 用户
ManagementService 执行cmd以及job
RuntimeService 流程实例
ProcessEngineConfiguration 流程引擎配置
ProcessEngine 流程引擎类
在Flowable中,流程的实现是依托于各个组件的相互依赖、组合而成的。ProcessEngine流程引擎是纵观整个Flowable应用的关键。通过构建ProcessEngine,我们可以从中拿到History的服务,Management服务,Repository服务,Form服务,Identity服务,Runtime服务以及Task服务。
ProcessEngine,引擎 API 是与 Flowable 交互的最常见方式。主要起点是 ProcessEngine,它可以通过配置部分中描述的多种方式创建。可以从 ProcessEngine 获取包含工作流/BPM 方法的各种服务。ProcessEngine 和服务对象是线程安全的,因此可以为整个服务器保留对其中之一的引用。
可以通过这个类获取其他常用类的对象
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 基于ProcessEngine获得Service服务
RuntimeService runtimeService = processEngine.getRuntimeService();
RepositoryService repositoryService = processEngine.getRepositoryService();
TaskService taskService = processEngine.getTaskService();
ManagementService managementService = processEngine.getManagementService();
IdentityService identityService = processEngine.getIdentityService();
HistoryService historyService = processEngine.getHistoryService();
FormService formService = processEngine.getFormService();
DynamicBpmnService dynamicBpmnService = processEngine.getDynamicBpmnService();
ProcessEngines.getDefaultProcessEngine() 将在第一次调用时初始化并构建流程引擎,然后始终返回相同的流程引擎。可以使用 ProcessEngines.init() 和 ProcessEngines.destroy() 正确创建和关闭所有流程引擎。所有服务都是无状态的。这意味着您可以轻松地在集群中的多个节点上运行 Flowable,每个节点都访问同一个数据库,而不必担心哪台机器实际执行了先前的调用。无论在何处执行,对任何服务的任何调用都是幂等的
创建Flowable工作流的配置对象,设置驱动全限定类名,设置jdbc连接用户名,设置连接密码,设置连接数据库的数据库连接地址,设置数据库策加载策略。
package org.flowable.springboot.demo.config;
import org.flowable.common.engine.impl.AbstractEngineConfiguration;
import org.flowable.engine.ProcessEngineConfiguration;
import org.flowable.engine.impl.cfg.StandaloneProcessEngineConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* @author fntp
*/
@Component
public class MyProcessEngineConfiguration {
@Resource
private DataSourceProperties properties;
/**
* 获得一个ProcessEngine配置对象
* @return 返回一个ProcessEngine的MySQL配置对象
*/
public ProcessEngineConfiguration getConfiguration(){
return new StandaloneProcessEngineConfiguration().setJdbcDriver(properties.getDriverClassName())
.setJdbcUsername(properties.getUsername())
.setJdbcPassword(properties.getPassword())
.setJdbcUrl(properties.getUrl())
.setDatabaseSchemaUpdate(AbstractEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
}
}
我们直接看一下FLowable是如何在直接子类中做的实现:
public ProcessEngine buildProcessEngine() {
// 首先是一些列的Init初始化方法,吧所有待加载的对象全部初始化
this.init();
// 创建一个ProcessEngine的实现类对象,将当前配置对象作为参数传递进去
ProcessEngineImpl processEngine = new ProcessEngineImpl(this);
// 如果流程引擎解释器控制器在流程启动后加载成功
if (this.handleProcessEngineExecutorsAfterEngineCreate) {
// 那么直接调用流程引擎对象的内部API,启动解释器
processEngine.startExecutors();
}
// 如果启动了Flowable内部的兼容器 并且 兼容器控制器也初始化成功
if (this.flowable5CompatibilityEnabled && this.flowable5CompatibilityHandler != null) {
// 命令解释器解析指令
this.commandExecutor.execute(new Command<Void>() {
// 具体解析的过程
public Void execute(CommandContext commandContext) {
ProcessEngineConfigurationImpl.this.flowable5CompatibilityHandler.getRawProcessEngine();
return null;
}
});
}
// 流程引擎的进一步初始化
this.postProcessEngineInitialisation();
// 返回流程引擎对象
return processEngine;
}
// 流程引擎的进一步初始化
protected void postProcessEngineInitialisation() {
if (this.validateFlowable5EntitiesEnabled) {
this.commandExecutor.execute(new ValidateV5EntitiesCmd());
}
if (this.redeployFlowable5ProcessDefinitions) {
this.commandExecutor.execute(new RedeployV5ProcessDefinitionsCmd());
}
if (this.performanceSettings.isValidateExecutionRelationshipCountConfigOnBoot()) {
this.commandExecutor.execute(new ValidateExecutionRelatedEntityCountCfgCmd());
}
if (this.performanceSettings.isValidateTaskRelationshipCountConfigOnBoot()) {
this.commandExecutor.execute(new ValidateTaskRelatedEntityCountCfgCmd());
}
if (this.flowable5CompatibilityEnabled) {
this.flowable5CompatibilityHandler.setJobProcessor(this.flowable5JobProcessors);
}
}
不继续深入了
RepositoryService 类
这个类用于流程的部署等管理
简单测试:、
部署
@Test
public void DeployProcess(){
Deployment holiday = repositoryService.createDeployment()
.addClasspathResource("测试流程图.bpmn20.xml")
.name("测试流程部署")
.deploy();
}
查询
@Test
public void DeploySelect(){
//批量查询
List<Deployment> list = repositoryService.createDeploymentQuery().list();
//批量分页查询
List<Deployment> listPage = repositoryService.createDeploymentQuery().listPage(0,10);
//精确查询只能返回一个 如果有多条记录会报错singleResult()
Deployment deployment = repositoryService.createDeploymentQuery().deploymentNameLike("测试流程部署").singleResult();
list.forEach(e->{
System.out.println(e.getName()+"list查询");
});
listPage.forEach(e->{
System.out.println(e.getName()+"listPage查询");
});
System.out.println(deployment.getName()+"精确查询");
}
//通过自定义sql这些查询
@Test
public void processSelect(){
List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery().list();
List<ProcessDefinition> list1 = repositoryService.createNativeProcessDefinitionQuery().sql("select *from ACT_RE_PROCDEF").list();
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionKey("day01").singleResult();
list.forEach(e->{
System.out.println(e.getName()+"list查询");
});
list1.forEach(e->{
System.out.println(e.getName()+"自己写 自定义sql 查询");
});
System.out.println(processDefinition.getName()+"精确查询");
}
//还有很多查询都差不多
DeploymentQuery deploymentId(String var1);
DeploymentQuery deploymentIds(List<String> var1);
DeploymentQuery deploymentName(String var1);
DeploymentQuery deploymentNameLike(String var1);
DeploymentQuery deploymentCategory(String var1);
DeploymentQuery deploymentCategoryLike(String var1);
DeploymentQuery deploymentCategoryNotEquals(String var1);
DeploymentQuery deploymentKey(String var1);
DeploymentQuery deploymentKeyLike(String var1);
DeploymentQuery deploymentTenantId(String var1);
DeploymentQuery deploymentTenantIdLike(String var1);
DeploymentQuery deploymentWithoutTenantId();
DeploymentQuery deploymentEngineVersion(String var1);
DeploymentQuery deploymentDerivedFrom(String var1);
DeploymentQuery parentDeploymentId(String var1);
DeploymentQuery parentDeploymentIdLike(String var1);
DeploymentQuery parentDeploymentIds(List<String> var1);
DeploymentQuery processDefinitionKey(String var1);
DeploymentQuery processDefinitionKeyLike(String var1);
DeploymentQuery latest();
DeploymentQuery orderByDeploymentId();
DeploymentQuery orderByDeploymentName();
DeploymentQuery orderByDeploymentTime();
DeploymentQuery orderByTenantId();
流程的激活与挂起
@Test
public void suspendActivateProcess(){
//使用流程定义的ID先查询到流程
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
.processDefinitionKey("day01").singleResult();
// isSuspended方法是在激活的时候返回true
boolean suspended = processDefinition.isSuspended();
if(suspended){
//挂起流程
repositoryService.activateProcessDefinitionById(processDefinition.getId());
System.out.println("激活流程...");
}else {
//激活流程
repositoryService.suspendProcessDefinitionById(processDefinition.getId());
System.out.println("挂起流程...");
}
删除流程部署
@Test
public void deleteDeploy(){
Deployment deployment = repositoryService.createDeploymentQuery().deploymentNameLike("测试流程部署").singleResult();
// 删除指定流程部署,如果存在该流程部署的实例job或者历史任务,都会抛出异常
repositoryService.deleteDeployment(deployment.getId());
// 级联删除该流程部署所创建的所有任务信息和历史数据
// repositoryService.deleteDeployment(deployment.getId(),true);
}
指定流程 启动人
@Test
public void processStatrUser(){
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
.processDefinitionKey("day01").singleResult();
//并不会去验证 用户是否存在 。需要我们业务处理
repositoryService.addCandidateStarterUser(processDefinition.getId(),"张三");
}
删除流程 启动人
public void processdeleteUser(){
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
.processDefinitionKey("day01").singleResult();
repositoryService.deleteCandidateStarterUser(processDefinition.getId(),"张三");
}
DynamicBpmnService 类
一个新增的服务,用于动态修改流程中的一些参数信息等,是引擎中的一个辅助的服务,可用于修改流程定义中的部分内容,而不需要重新部署它。例如可以修改流程定义中一个用户任务的办理人设置,或者修改一个服务任务中的类名
HistoryService 类
Flowable的HistoryService提供了历史的查询服务,可以查询经过了哪些节点,进程的流程生成器ProcessDiagramGenerator,可以动态生成各种流程图,最后我们使用HttpServletResponse返回一个图像以供显示
判断是否完成
@Override
public boolean isFinished(String processInstanceId) {
return historyService.createHistoricProcessInstanceQuery().finished()
.processInstanceId(processInstanceId).count() > 0;
}
完成显示
@Override
public void genProcessDiagram(HttpServletResponse httpServletResponse, String processId) {
/**
* 获得当前活动的节点
*/
String processDefinitionId = "";
if (this.isFinished(processId)) {// 如果流程已经结束,则得到结束节点
HistoricProcessInstance pi = historyService.createHistoricProcessInstanceQuery().processInstanceId(processId).singleResult();
processDefinitionId=pi.getProcessDefinitionId();
} else {// 如果流程没有结束,则取当前活动节点
// 根据流程实例ID获得当前处于活动状态的ActivityId合集
ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(processId).singleResult();
processDefinitionId=pi.getProcessDefinitionId();
}
List<String> highLightedActivitis = new ArrayList<String>();
/**
* 获得活动的节点
*/
List<HistoricActivityInstance> highLightedActivitList = historyService.createHistoricActivityInstanceQuery().processInstanceId(processId).orderByHistoricActivityInstanceStartTime().asc().list();
for(HistoricActivityInstance tempActivity : highLightedActivitList){
String activityId = tempActivity.getActivityId();
highLightedActivitis.add(activityId);
}
List<String> flows = new ArrayList<>();
//获取流程图
BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
ProcessEngineConfiguration engconf = processEngine.getProcessEngineConfiguration();
ProcessDiagramGenerator diagramGenerator = engconf.getProcessDiagramGenerator();
InputStream in = diagramGenerator.generateDiagram(bpmnModel, "bmp", highLightedActivitis, 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);
}
} catch (IOException e) {
log.error("操作异常",e);
} finally {
IOUtils.closeQuietly(out);
IOUtils.closeQuietly(in);
}
}
FormService 表单
TaskService 任务
IdentityService 用户
ManagementService 执行cmd以及job
RuntimeService 流程实例
监听器(多实例会签任务全局监听器,自动跳过流程任务监听, 全局监听-工作流待办消息提醒等等)
前端集成表单设计器
后端集成flowable
一个小demo(前后端集成)
有时间再写