Flowable进阶学习(十)定时器、ServiceTask服务任务、ScriptTask脚本任务

一、定时器

相关知识链接阅读:事件网关——定时器启动事件

1. 流程定义定时激活

可以通过activateProcessDefinitionsOn(date)给流程定义设置一个启动时间。这个流程就会延迟激活。在激活之前,无法启动该流程。

  1. 部署流程
@Test
void test_delayDeploy() {
    Deployment deploy = repositoryService.createDeployment()
            .addClasspathResource("process/请假Demo.bpmn20.xml")
            .name("deployName-定时启动")
            // 表示延迟1分钟激活流程定义
            .activateProcessDefinitionsOn(new Date(System.currentTimeMillis() + 1000 * 60))
            .key("deployKey-dsqd").deploy();
    System.out.println("deploy.getId() = " + deploy.getId());
}
  1. 启动测试
@Test
void startFlow(){
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(PROC_KEY);
    System.out.println("processInstance.getId() = " + processInstance.getId());
}

当我们在流程定义还未到时激活的时候,来启动一个流程,则会抛出异常:流程定义挂起

org.flowable.common.engine.api.FlowableException: Cannot start process instance. Process definition 请假Demo (id = qj-demo:1:d91875ee-a88c-11ed-a56b-c83dd4896099) is suspended

我们查看ACT_RU_TIMER_JOB表,可以看到表中有一条任务记录,其中DUEDATE_是处理时间(当时间到达或超过自动处理,会将ACT_RE_PROCDEF表的SUSPENSION_STATE_状态2变更为1), HANDLER_TYPE_是激活流程定义,HANDLER_CFG_ 是否包含流程实例。
在这里插入图片描述

2. 流程实例定时挂起

@Test
void test_Suspend() throws InterruptedException {
    // 设置30秒后自动挂起该流程定义与流程实例
    Date suspensionDate = new Date(System.currentTimeMillis() + 1000 * 30);
    // 这个方法是挂起流程定义的方法
    repositoryService.suspendProcessDefinitionByKey(PROC_KEY, true, suspensionDate);
    // 这个方法是流程实例的挂起方法
//        runtimeService.suspendProcessInstanceById("id001");
    Thread.sleep(30);
    ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
            .processDefinitionKey(PROC_KEY).latestVersion().singleResult();
    System.out.println("processDefinition.getName() = " + processDefinition.getName());
    System.out.println("processDefinition.isSuspended() = " + processDefinition.isSuspended());
    List<ProcessInstance> list = runtimeService.createProcessInstanceQuery().processDefinitionKey(PROC_KEY).list();
    for (ProcessInstance instance : list) {
        System.out.println("instance.isSuspended() = " + instance.isSuspended());
    }
}

3. 定时任务执行过程

ManagementService方法名作用涉及表变动
moveTimerToExecutableJob(job.getId());将定时任务移动到执行ACT_RU_TIMER_JOB -> ACT_RU_JOB
moveJobToDeadLetterJob(job.getId());将任务移动到死信任务ACT_RU_TIMER_JOB -> ACT_RU_DEADLETTER_JOB
`moveDeadLetterJobToExecutableJob(job.getId(), 1)移动死信任务到执行任务ACT_RU_DEADLETTER_JOB -> ACT_RU_JOB
createTimerJobQuery()查询定时任务ACT_RU_TIMER_JOB
createDeadLetterJobQuery()查询死信任务ACT_RU_DEADLETTER_JOB

任务相关表信息

表名含义
ACT_RU_TIMER_JOB定时作业表
ACT_RU_JOB运行时作业表(进入运行时作业表的任务会被立即执行)
ACT_RU_HISTORY_JOB历史作业表
ACT_RU_DEADLETTER_JOB死信作业表(DeadLetter:死信、退件、空文,存放取消的定时作业)
ACT_RU_SUSPENDED_JOB挂起作业表
ACT_RU_EXTERNAL_JOB外部作业表
/**
 * 延迟5分钟激活
 *
 * @throws InterruptedException
 */
@Test
void test_activeProcess() throws InterruptedException {
    ProcessDefinition pd = repositoryService.createProcessDefinitionQuery()
            .processDefinitionKey(PROC_KEY)
            .latestVersion().singleResult();
    // 延迟5分钟激活流程定义与实例
    Date activationDate = new Date(System.currentTimeMillis() + 5 * 60 * 1000);
    System.out.println("pd.isSuspended() = " + pd.isSuspended());
    if (!pd.isSuspended()) {
        repositoryService.suspendProcessDefinitionById(pd.getId());
    }
    repositoryService.activateProcessDefinitionById(pd.getId(), true, activationDate);
    //org.flowable.common.engine.api.FlowableException: Cannot set suspension state 'suspended' for ProcessDefinitionEntity[qj-demo:1:d91875ee-a88c-11ed-a56b-c83dd4896099]': already in state 'suspended'.
}

/**
 * 查询并立即激活
 *
 * @throws InterruptedException
 */
@Test
void queryAndActiveNow() throws InterruptedException {
    ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
            .processDefinitionKey(PROC_KEY)
            .latestVersion().singleResult();
    System.out.println("processDefinition.isSuspended() = " + processDefinition.isSuspended());
    List<Job> list = managementService.createTimerJobQuery().processDefinitionId(processDefinition.getId()).list();
    list.forEach(job -> {
        managementService.moveTimerToExecutableJob(job.getId());
    });
    Thread.sleep(30);
    ProcessDefinition pd = repositoryService.createProcessDefinitionQuery()
            .processDefinitionKey(PROC_KEY)
            .latestVersion().singleResult();
    System.out.println("pd.isSuspended() = " + pd.isSuspended());
}

/**
 * 延迟5分钟挂起
 *
 * @throws InterruptedException
 */
@Test
void test_suspendedProcess() throws InterruptedException {
    ProcessDefinition pd = repositoryService.createProcessDefinitionQuery()
            .processDefinitionKey(PROC_KEY)
            .latestVersion().singleResult();
    // 延迟5分钟激活流程定义与实例
    Date activationDate = new Date(System.currentTimeMillis() + 2 * 60 * 1000);
    System.out.println("pd.isSuspended() = " + pd.isSuspended());
    if (pd.isSuspended()) {
        repositoryService.activateProcessDefinitionById(pd.getId());
    }
    repositoryService.suspendProcessDefinitionById(pd.getId(), true, activationDate);
}

/**
 * 查询并立即挂起
 *
 * @throws InterruptedException
 */
@Test
void queryAndSuspendedNow() throws InterruptedException {
    ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
            .processDefinitionKey(PROC_KEY)
            .latestVersion().singleResult();
    System.out.println("processDefinition.isSuspended() = " + processDefinition.isSuspended());
    // 定时任务查询
    List<Job> list = managementService.createTimerJobQuery().processDefinitionId(processDefinition.getId()).list();
    list.forEach(job -> {
        managementService.moveJobToDeadLetterJob(job.getId());
    });
    Thread.sleep(60 * 1000);
    // deadLetter 死信、空文、退件
    // 从退件任务队列查询
    List<Job> deadLetterJobs = managementService.createDeadLetterJobQuery().processDefinitionId(processDefinition.getId()).list();
    deadLetterJobs.forEach(job -> {
        // 将退件任务移到执行列表
        managementService.moveDeadLetterJobToExecutableJob(job.getId(), 1);
//            managementService.moveDeadLetterJobToHistoryJob(job.getId(),1);
    });
    Thread.sleep(60 * 1000);
    ProcessDefinition pd = repositoryService.createProcessDefinitionQuery()
            .processDefinitionKey(PROC_KEY)
            .latestVersion().singleResult();
    System.out.println("pd.isSuspended() = " + pd.isSuspended());
}

ServiceTask 服务任务

ServiceTask一般由系统自动完成,当系统走到这一步的时候,不会停下,会自动执行我们在ServiceTask配置的方法。
![在这里插入图片描述](https://img-blog.csdnimg.cn/e04fdfc226ca495091933b45ec8ad241.png

委托表达式

在这里插入图片描述
实现了JavaDelegate的接口,注入Spring容器,在配置中可以不写完整类名,只需要写Spring容器名称即可。首字母小写${myServiceTask}

@Component
public class MyServiceTask implements JavaDelegate {
    @Autowired
    TaskService taskService;
    @Autowired
    RuntimeService runtimeService;

    @Override
    public void execute(DelegateExecution execution) {
        System.out.println("========MyServiceTask2==========");
        System.out.println("execution = " + execution);
//        execution.getCurrentActivityId()

    }
}

表达式

表达式可以是普通类中的一个方法${myServiceTask2.hello()}

类中字段

在这里插入图片描述

Expression userName;

@Override
public void execute(DelegateExecution execution) {
    System.out.println("========MyServiceTask2==========");
    System.out.println("execution = " + execution);
    if (userName != null) {
        System.out.println("username.getExpressionText() = " + userName.getExpressionText());
        System.out.println("username.getValue(execution) = " + userName.getValue(execution));
    }
}

ScriptTask 脚本任务

脚本任务,当流程到达该节点的时候,自动执行脚本。可以有JS(JavaScript)、Groovy、Juel脚本。

JS TASK

在这里插入图片描述
需要注意的是JS脚本不支持ES6语法。
部署流程

@Test
void doDeploy2() {
    Deployment deploy = repositoryService.createDeployment()
            .addClasspathResource("process/脚本任务demo.bpmn20.xml")
            .deploy();
    System.out.println("deploy.getId() = " + deploy.getId());
}

启动流程与查询流程变量

@Test
void jsTask() {
    Map<String, Object> variables = new HashMap<>();
    variables.put("a", 99);
    variables.put("b", 98);
    ProcessInstance pi = runtimeService.startProcessInstanceByKey("js-task", variables);
    System.out.println("pi.getId() = " + pi.getId());
    System.out.println("pi.getActivityId() = " + pi.getActivityId());
    System.out.println("pi.getProcessVariables() = " + pi.getProcessVariables());
}
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Huathy-雨落江南,浮生若梦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值