学习来源视频地址感兴趣的可以一起学习。
flowable官网链接
Flowable 工作流(三)
流程挂起和激活
我们先查看数据库中的流程定义状态信息,查看act_re_procdef的状态字段:SUSPENSION_STATE_,这里我们可以看得到,现在的流程状态是1(激活状态)。
接下来就来实现修改流程状态挂起或者激活。
获取流程引擎,查询流程定义id为MyHolidayUI:1:20004(流程ID根据自己的流程id修改)的流程定义信息。
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
//获取流程定义信息
ProcessDefinition singleResult = repositoryService.createProcessDefinitionQuery()
.processDefinitionId("MyHolidayUI:1:20004")
.singleResult();
可以通过它提供的一个方法得到一个Boolean类型的状态:
// 获取流程定义状态
boolean isSuspended = singleResult.isSuspended();
最后让它若是处于挂起状态的时候就将它改为激活反之挂起:
if (isSuspended) {
//流程挂起状态
// 激活流程
//参数说明:第一个参数是流程定义的id,第二个参数是是否激活,第三个参数是时间
repositoryService.activateProcessDefinitionById("MyHolidayUI:1:20004", true, null);
System.out.println("流程已激活");
} else {
//流程激活状态
// 挂起流程
//参数说明:第一个参数是流程定义的id,第二个参数是是否激活,第三个参数是时间
repositoryService.suspendProcessDefinitionById("MyHolidayUI:1:20004", true, null);
System.out.println("流程已挂起");
}
修改之后再来查看流程定义状态信息:
确定他已经被挂起了,然后我们来启动一下该流程定义看还能否被允许。
启动流程定义代码:
/**
* 启动一下被挂起的流程
*/
@Test
public void runProcess() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
processEngine.getRuntimeService().startProcessInstanceById("MyHolidayUI:1:20004");
}
很清楚的就发现,控制台报错了,而且还很清楚的说明了,流程定义已经被挂起:Cannot start process instance. Process definition MyHolidayUI (id = MyHolidayUI:1:20004) is suspended
org.flowable.common.engine.api.FlowableException: Cannot start process instance. Process definition MyHolidayUI (id = MyHolidayUI:1:20004) is suspended
at org.flowable.engine.impl.util.ProcessInstanceHelper.createProcessInstance(ProcessInstanceHelper.java:95)
at org.flowable.engine.impl.cmd.StartProcessInstanceCmd.startProcessInstance(StartProcessInstanceCmd.java:239)
at org.flowable.engine.impl.cmd.StartProcessInstanceCmd.execute(StartProcessInstanceCmd.java:128)
at org.flowable.engine.impl.cmd.StartProcessInstanceCmd.execute(StartProcessInstanceCmd.java:53)
at org.flowable.engine.impl.interceptor.CommandInvoker$1.run(CommandInvoker.java:67)
at org.flowable.engine.impl.interceptor.CommandInvoker.executeOperation(CommandInvoker.java:140)
at org.flowable.engine.impl.interceptor.CommandInvoker.executeOperations(CommandInvoker.java:114)
at org.flowable.engine.impl.interceptor.CommandInvoker.execute(CommandInvoker.java:72)
at org.flowable.engine.impl.interceptor.BpmnOverrideContextInterceptor.execute(BpmnOverrideContextInterceptor.java:26)
at org.flowable.common.engine.impl.interceptor.TransactionContextInterceptor.execute(TransactionContextInterceptor.java:53)
at org.flowable.common.engine.impl.interceptor.CommandContextInterceptor.execute(CommandContextInterceptor.java:105)
at org.flowable.common.engine.impl.interceptor.LogInterceptor.execute(LogInterceptor.java:30)
at org.flowable.common.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:56)
at org.flowable.common.engine.impl.cfg.CommandExecutorImpl.execute(CommandExecutorImpl.java:51)
at org.flowable.engine.impl.RuntimeServiceImpl.startProcessInstanceById(RuntimeServiceImpl.java:152)
at com.he.flowable.FlowableProcessTest.runProcess(FlowableProcessTest.java:51)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:725)
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$7(TestMethodTestDescriptor.java:214)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:210)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:66)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:151)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at java.util.ArrayList.forEach(ArrayList.java:1259)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at java.util.ArrayList.forEach(ArrayList.java:1259)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53)
at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:57)
at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:232)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:55)
启动流程实例
上边代码我们已经看到启动流程实例方法,当然它也可以加上一些参数,源码提供了多种启动方式,这里就列举流程定义id方式的。
他可以添加businessKey,这个字段数据表里边有,具体作用暂时没有搞懂,variables:流程信息,例如:请假,这里就可以有请假理由,开始时间,结束时间等。
/**
* Starts a new process instance in the exactly specified version of the process definition with the given id.
*
* @param processDefinitionId
* the id of the process definition, cannot be null.
* @throws FlowableObjectNotFoundException
* when no process definition is deployed with the given key.
*/
ProcessInstance startProcessInstanceById(String processDefinitionId);
/**
* Starts a new process instance in the exactly specified version of the process definition with the given id.
* <p>
* A business key can be provided to associate the process instance with a certain identifier that has a clear business meaning. For example in an order process, the business key could be an order
* id. This business key can then be used to easily look up that process instance , see {@link ProcessInstanceQuery#processInstanceBusinessKey(String)}. Providing such a business key is definitely
* a best practice.
*
* @param processDefinitionId
* the id of the process definition, cannot be null.
* @param businessKey
* a key that identifies the process instance and can be used to retrieve the process instance later via the query API.
* @throws FlowableObjectNotFoundException
* when no process definition is deployed with the given key.
*/
ProcessInstance startProcessInstanceById(String processDefinitionId, String businessKey);
/**
* Starts a new process instance in the exactly specified version of the process definition with the given id.
*
* @param processDefinitionId
* the id of the process definition, cannot be null.
* @param variables
* variables to be passed, can be null
* @throws FlowableObjectNotFoundException
* when no process definition is deployed with the given key.
*/
ProcessInstance startProcessInstanceById(String processDefinitionId, Map<String, Object> variables);
/**
* Starts a new process instance in the exactly specified version of the process definition with the given id.
* <p>
* A business key can be provided to associate the process instance with a certain identifier that has a clear business meaning. For example in an order process, the business key could be an order
* id. This business key can then be used to easily look up that process instance , see {@link ProcessInstanceQuery#processInstanceBusinessKey(String)}. Providing such a business key is definitely
* a best practice.
*
* @param processDefinitionId
* the id of the process definition, cannot be null.
* @param variables
* variables to be passed, can be null
* @throws FlowableObjectNotFoundException
* when no process definition is deployed with the given key.
*/
ProcessInstance startProcessInstanceById(String processDefinitionId, String businessKey, Map<String, Object> variables);
当启动一个流程实例后,会在**ACT_RU_***对应的表结构里边操作,运行实例涉及的表结构有如下一些:
- ACT_RU_DEADLETTER_JOB 正在运行的任务表
- ACT_RU_EVENT_SUBSCR 运行时事件
- ACT_RU_EXECUTION 运行时流程执行实例
- ACT_RU_HISTORY_JOB 历史作业表
- ACT_RU_IDENTITYLINK 运行时用户关系信息表
- ACT_RU_JOB 运行时作业表
- ACT_RU_SUSPENDED_JOB 暂停作业表
- ACT_RU_TASK 运行时任务表
- ACT_RU_TIMER_JOB 定时作业表
- ACT_RU_VARIABLE 运行时变量表
分配任务-UEL表达式
启动flowable-ui,我们继续在里边操作创建流程。
1、创建一个简单的流程:
给流程创建者和流程审批者分别使用UEL表达式指定。
首先选中创建者–>选择分配用户
选择固定值设置一个表达式(可以自己随意但是必须使用${}包着)另外一个同样设置。然后保存。
把制作好的流程下载放到程序中,其实也可以直接在idea中制作,一样的。
1、代码部署了,部署还不会的查看一下前面两篇。
2、启动流程实例
运行时变量:
查看运行时任务表发现assignee0已经被解析出来了【张翠山】
监听器分配
创建一个监听器:
import org.flowable.engine.delegate.TaskListener;
import org.flowable.task.service.delegate.DelegateTask;
/**
* @author HEXIONLY
* @datetime 2024/04/22 22:39:35
*/
public class MyTaskListener implements TaskListener {
@Override
public void notify(DelegateTask delegateTask) {
}
}
仔细看就会发现类似于刚开始时的官网示例流程中的发邮件的。