flowabe内置了任务超时字段,但是并没有对应的事件处理机制,为了满足任务处理时的超时提醒及超时后的处理,通过flowable的定时任务机制,扩展执行命令来实现超时处理。
1、flowable初始化时,注册超时事件处理类
@Configuration
public class FlowableConfiguration implements EngineConfigurationConfigurer<SpringProcessEngineConfiguration> {
@Override
public void configure(SpringProcessEngineConfiguration springProcessEngineConfiguration) {
springProcessEngineConfiguration.setActivityBehaviorFactory(customActivityBehaviorFactory());
springProcessEngineConfiguration.setAsyncExecutorActivate(true);
springProcessEngineConfiguration.setAsyncExecutor(springAsyncExecutor());
springProcessEngineConfiguration.addCustomJobHandler(timeoutHandler());
}
@Bean
public CustomActivityBehaviorFactory customActivityBehaviorFactory() {
return new CustomActivityBehaviorFactory();
}
@Bean
public SpringAsyncExecutor springAsyncExecutor() {
return new SpringAsyncExecutor();
}
@Bean
public TimeoutHandler timeoutHandler() {
return new TimeoutHandler();
}
}
2、 添加用户任务超时处理类
@Slf4j
public class TimeoutHandler implements JobHandler {
public static final String TYPE = "timeout-handler";
@Override
public String getType() {
return TYPE;
}
@Override
public void execute(JobEntity jobEntity, String params, VariableScope variableScope, CommandContext commandContext) {
log.info("============执行自定义定时任务============");
log.info("定时任务详情={},参数={}", JSON.toJSONString(jobEntity), params);
}
}
3、添加flowable定时任务命令类
public class TimeoutCommand implements Command<Void>, Serializable {
protected String processInstanceId;
protected JSONObject params;
protected String executionId;
protected Date dueDate;
public TimeoutCommand(String processInstanceId, JSONObject params, String executionId, Date dueDate) {
this.processInstanceId = processInstanceId;
this.executionId = executionId;
this.dueDate = dueDate;
this.params = params;
}
@Override
public Void execute(CommandContext commandContext) {
TimerJobService timerJobService = CommandContextUtil.getTimerJobService(commandContext);
TimerJobEntity job = timerJobService.createTimerJob();
job.setJobType(Job.JOB_TYPE_TIMER);
job.setExclusive(true);
// 作业处理器类型
job.setJobHandlerType(TimeoutHandler.TYPE);
// 处理时间
job.setDuedate(this.dueDate);
job.setExecutionId(null);
job.setProcessInstanceId(this.processInstanceId);
job.setJobHandlerConfiguration(params.toJSONString());
timerJobService.scheduleTimerJob(job);
return null;
}
}
4、在需要处理的地方添加定时任务,例如用户任务创建之后
public class GlobalListener extends AbstractFlowableEngineEventListener {
@Override
protected void taskCreated(FlowableEngineEntityEvent event) {
super.taskCreated(event);
if (event instanceof FlowableEntityEventImpl) {
ManagementService managementService = CommandContextUtil.getProcessEngineConfiguration().getManagementService();
TaskService taskService = CommandContextUtil.getProcessEngineConfiguration().getTaskService();
new Thread(() -> {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 任务实例
TaskEntity entity = (TaskEntity) event.getEntity();
Task task = taskService.createTaskQuery()
.taskId(entity.getId())
.includeIdentityLinks()
.singleResult();
if (task != null && task.getDueDate() != null) {
managementService.executeCommand(new TimeoutCommand(task.getProcessInstanceId(), new JSONObject().fluentPut("taskId", task.getId()), null, task.getDueDate(), "add"));
}
}).start();
}
}
}
5、项目启动成功后注册任务创建监听器
@Configuration
@AllArgsConstructor
public class WfGlobListenerConfig implements ApplicationListener<ContextRefreshedEvent> {
private final GlobalListener globalListener;
private final RuntimeService runtimeService;
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
// 任务创建时
runtimeService.addEventListener(globalListener, FlowableEngineEventType.TASK_CREATED);
}
}