精华内容
下载资源
问答
  • 最近有个需求,需要实现审批任务超时自动跳过的功能,虽然flowable自带的边缘事件也可以快速的实现,但使用自定义的作业处理器更加灵活方便,能处理更复杂的业务逻辑。 1. 开启定时任务 flowable: async-...

    最近有个需求,需要实现审批任务超时自动跳过的功能,虽然flowable自带的边缘事件也可以快速的实现,但使用自定义的作业处理器更加灵活方便,能处理更复杂的业务逻辑。

    1. 开启定时任务

    flowable:
      async-executor-activate: true

    2. 实现自定义作业处理器

    Flowable采用HashMap(<type -> JobHandler>)维护全局的作业处理器集合jobHandlers,在ProcessEngineConfigurationImpl.java的initJobHandlers方法中初始化了8个默认的作业处理器以及自定义作业处理器,如下:

    public void initJobHandlers() {
            jobHandlers = new HashMap<>();
    
            AsyncContinuationJobHandler asyncContinuationJobHandler = new AsyncContinuationJobHandler();
            jobHandlers.put(asyncContinuationJobHandler.getType(), asyncContinuationJobHandler);
            
            AsyncTriggerJobHandler asyncTriggerJobHandler = new AsyncTriggerJobHandler();
            jobHandlers.put(asyncTriggerJobHandler.getType(), asyncTriggerJobHandler);
    
            TriggerTimerEventJobHandler triggerTimerEventJobHandler = new TriggerTimerEventJobHandler();
            jobHandlers.put(triggerTimerEventJobHandler.getType(), triggerTimerEventJobHandler);
    
            TimerStartEventJobHandler timerStartEvent = new TimerStartEventJobHandler();
            jobHandlers.put(timerStartEvent.getType(), timerStartEvent);
    
            TimerSuspendProcessDefinitionHandler suspendProcessDefinitionHandler = new TimerSuspendProcessDefinitionHandler();
            jobHandlers.put(suspendProcessDefinitionHandler.getType(), suspendProcessDefinitionHandler);
    
            TimerActivateProcessDefinitionHandler activateProcessDefinitionHandler = new TimerActivateProcessDefinitionHandler();
            jobHandlers.put(activateProcessDefinitionHandler.getType(), activateProcessDefinitionHandler);
    
            ProcessEventJobHandler processEventJobHandler = new ProcessEventJobHandler();
            jobHandlers.put(processEventJobHandler.getType(), processEventJobHandler);
            
            AsyncCompleteCallActivityJobHandler asyncCompleteCallActivityJobHandler = new AsyncCompleteCallActivityJobHandler();
            jobHandlers.put(asyncCompleteCallActivityJobHandler.getType(), asyncCompleteCallActivityJobHandler);
    
            // if we have custom job handlers, register them
            if (getCustomJobHandlers() != null) {
                for (JobHandler customJobHandler : getCustomJobHandlers()) {
                    jobHandlers.put(customJobHandler.getType(), customJobHandler);
                }
            }
        }

    所有默认的作业处理器都实现了JobHandler接口,所以这里先依葫芦画瓢写一个实现JobHandler接口的自定义作业处理器:

    @Slf4j
    @Component
    public class BpmCustomJobHandler implements JobHandler {
        public static final String TYPE = "custom-handler";
    
        @Override
        public String getType() {
            return "custom-handler";
        }
    
        @Override
        public void execute(JobEntity jobEntity, String s, VariableScope variableScope, CommandContext commandContext) {
            log.info("============执行自定义定时任务============");
            log.info("定时任务详情={}", JSON.toJSONString(jobEntity));
        }
    }

    在DefaultJobManager.java的executeJobHandler方法中可以看到,这里的type是用来在jobHandlers集合中匹配作业处理器用的,可以是任意字符串,只要不和已有的重复即可。

    protected void executeJobHandler(JobEntity jobEntity) {
            VariableScope variableScope = this.jobServiceConfiguration.getInternalJobManager().resolveVariableScope(jobEntity);
            Map<String, JobHandler> jobHandlers = this.jobServiceConfiguration.getJobHandlers();
            if (jobEntity.getJobHandlerType() != null) {
                JobHandler jobHandler = (JobHandler)jobHandlers.get(jobEntity.getJobHandlerType());
                if (jobHandler != null) {
                    jobHandler.execute(jobEntity, jobEntity.getJobHandlerConfiguration(), variableScope, this.getCommandContext());
                } else {
                    throw new FlowableException("No job handler registered for type " + jobEntity.getJobHandlerType());
                }
            } else {
                throw new FlowableException("Job has no job handler type");
            }
        }
    
    

    3. 注册自定义作业处理器

    在配置类中加入以下代码,即可在初始化时将自定义作业处理器加入jobHandlers集合中。

    @Bean
    public EngineConfigurationConfigurer<SpringProcessEngineConfiguration> customEngineConfiguration() {
        return engineConfiguration -> engineConfiguration.addCustomJobHandler(new BpmCustomJobHandler());
    }

    4. 添加定时任务

    使用命令模式在act_ru_timer_job表中添加一条定时任务记录。

    public class CustomJobCmd implements Command<Void>, Serializable {
        protected String processInstanceId;
        protected String taskId;
        protected String executionId;
        protected Date dueDate;
        protected String type;
        protected String comment;
    
        public CustomJobCmd(String processInstanceId, String comment, String taskId, String executionId, Date dueDate, String type) {
            this.processInstanceId = processInstanceId;
            this.comment = comment;
            this.taskId = taskId;
            this.executionId = executionId;
            this.dueDate = dueDate;
            this.type = type;
        }
    
        @Override
        public Void execute(CommandContext commandContext) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("comment", this.comment);
            jsonObject.put("task_id", this.taskId);
    
            TimerJobService timerJobService = CommandContextUtil.getTimerJobService(commandContext);
            TimerJobEntity job = timerJobService.createTimerJob();
            job.setJobType(Job.JOB_TYPE_TIMER);
            job.setExclusive(true);
            // 作业处理器类型
            job.setJobHandlerType(BpmCustomJobHandler.TYPE);
            // 处理时间
            job.setDuedate(this.dueDate);
            job.setExecutionId(null);
            job.setProcessInstanceId(this.processInstanceId);
            job.setJobHandlerConfiguration(jsonObject.toJSONString());
            timerJobService.scheduleTimerJob(job);
            return null;
        }
    }

    在需要添加定时任务的地方,执行命令。

    managementService.executeCommand(new CustomJobCmd("350022", "测试", "350061", null, dueDate, "add"));

    执行完毕后,可以在act_ru_timer_job表中看到成功添加了一条记录。

     定时任务执行效果:

    展开全文
  • 2.18 事件处理器(Event handlers) The event mechanism in the Flowable engine allows you to get notified when various events occur within the engine. Take a look at all supported event types for an ...

    Flowable 6.6.0 用户指南相关文档下载


    《Flowable 6.6.0 BPMN用户指南》

    2. 配置

    有关Flowable文档的其他资料,参见:

    《Flowable文档大全》

    2.18 事件处理器(Event handlers)

    The event mechanism in the Flowable engine allows you to get notified when various events occur within the engine. Take a look at all supported event types for an overview of the events available.

    It’s possible to register a listener for certain types of events as opposed to getting notified when any type of event is dispatched. You can either add engine-wide event listeners through the configuration, add engine-wide event listeners at runtime using the API or add event-listeners to specific process definitions in the BPMN XML.

    Flowable引擎中的事件机制允许您在引擎内发生各种事件时得到通知。查看所有支持的事件类型(all supported event types),以获取可用事件的概述。

    可以为某些特定类型的事件注册侦听器,而不是在分发所有类型的事件时都得到通知。您可以通过配置(through the configuration)添加引擎范围(engine-wide)的事件侦听器,使用API在运行时(at runtime using the API)添加引擎范围的事件侦听器,或者将事件侦听器添加到BPMN XML中的特定流程定义(specific process definitions in the BPMN XML)中。

    All events dispatched are a subtype of org.flowable.engine.common.api.delegate.event.FlowableEvent. The event exposes (if available) the type, executionId, processInstanceId and processDefinitionId. Certain events contain additional context related to the event that occurred, more information about additional payloads can be found in the list of all supported event types.

    所有发出的事件都是org.flowable.engine.common.api.delegate.event.FlowableEvent的子类型。事件暴露了(如果具有)type,executionId, processInstanceId 和 processDefinitionId。某些事件包含了与发生的事件相关的更多的上下文。有关有效负载的更多信息可以在所有支持的事件类型的列表中(all supported event types)找到。

    2.18.1 事件侦听器(event-listener)实现

    The only requirement for an event-listener is to implement org.flowable.engine.delegate.event.FlowableEventListener. Below is an example implementation of a listener, which outputs all events received to the standard-out, with exception of events related to job-execution:

    事件侦听器(event-listener)的唯一要求是实现org.flowable.engine.delegate.event.FlowableEventListener.
    以下是一个侦听器的实现示例,它将接收到的所有事件输出到标准输出(standard-out),但与作业执行(job-execution)相关的事件除外:

    public class MyEventListener implements FlowableEventListener {
    
      @Override
      public void onEvent(FlowableEvent event) {
    
        if(event.getType() == FlowableEngineEventType.JOB_EXECUTION_SUCCESS) {
          System.out.println("A job well done!");
        } else if (event.getType() == FlowableEngineEventType.JOB_EXECUTION_FAILURE) {
          System.out.println("A job has failed...");
        } else {
          System.out.println("Event received: " + event.getType());
        }
      }
    
      @Override
      public boolean isFailOnException() {
        // The logic in the onEvent method of this listener is not critical, exceptions
        // can be ignored if logging fails...
        return false;
      }
    
      @Override
      public boolean isFireOnTransactionLifecycleEvent() {
        return false;
      }
    
      @Override
      public String getOnTransaction() {
        return null;
      }
    }
    

    The isFailOnException() method determines the behavior when the onEvent(…) method throws an exception when an event is dispatched. When false is returned, the exception is ignored. When true is returned, the exception is not ignored and bubbles up, effectively failing the current ongoing command. If the event was part of an API-call (or any other transactional operation, for example, job-execution), the transaction will be rolled back. If the behavior in the event-listener is not business-critical, it’s recommended to return false.

    isFailOnException()方法确定:当引发事件、onEvent(…)方法抛出异常时的行为。当返回false时,将忽略异常。当返回true时,异常不会被忽略,并且会出现向上冒泡传递(bubble up),实际上会使当前正在执行的命令失败。如果事件是API调用(或任何其他事务性操作,例如作业执行)的一部分,则事务将回滚。如果事件侦听器中的行为不是业务关键型的(business-critical),那么建议返回false。

    The isFireOnTransactionLifecycleEvent() method determines whether this event listener fires immediately when the event occurs or on a transaction lifecycle event determined by getOnTransaction() method. Supported values of the transaction life cycle event are: COMMITTED, ROLLED_BACK, COMMITTING, ROLLINGBACK.

    isFireOnTransactionLifecycleEvent ( )方法确定此事件侦听器是在事件发生时立即触发,还是在由getOnTransaction ( )方法确定的事务生命周期事件(transaction lifecycle event)上触发。事务生命周期事件(transaction lifecycle event)支持的值为:

    • 已提交(COMMITTED)
    • 已回滚(ROLLED_BACK)
    • 提交中(COMMITTING)
    • 回滚中(ROLLINGBACK)

    There are a few base implementations provided by Flowable to facilitate common use cases of event-listeners. These can be used as base-class or as an example listener implementation:

    • org.flowable.engine.delegate.event.BaseEntityEventListener: An event-listener base-class that can be used to listen for entity-related events for a specific type of entity or for all entities. It hides away the type-checking and offers 4 methods that should be overridden: onCreate(…), onUpdate(…) and onDelete(…) when an entity is created, updated or deleted. For all other entity-related events, the onEntityEvent(…) is called.

    Flowable提供了一些基本实现,以快速实现常用的事件侦听器用例。这些可以用作基类或作为示例侦听器实现:

    • org.flowable.engine.delegate.event.BaseEntityEventListener: 事件侦听器基类(event-listener base-class),可用于侦听特定类型实体或所有实体的与实体相关的事件(entity-related events)。它隐藏了类型检查,并提供了4个应该被重写的方法:onCreate(…)、onUpdate(…)和onDelete(…),分别用于当实体被创建、更新或删除时。对于所有其他与实体相关的事件,将调用onEntityEvent(…)。
    展开全文
  • 该楼层疑似违规已被系统折叠隐藏此楼查看此楼做工作流产品的实施有很多年了,也加了很多诸如 activiti flowable **pm 等社区和群聊。发现很多人在走弯路,深陷泥潭不可自拔。所以写了这篇文章,旨在告诉很多走向了...

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼

    做工作流产品的实施有很多年了,也加了很多诸如 activiti flowable **pm 等社区和群聊。

    发现很多人在走弯路,深陷泥潭不可自拔。

    所以写了这篇文章,旨在告诉很多走向了activiti flowable整合道路的兄弟们,切勿太过于深入整合。

    推荐下个人开源项目 https://gitee.com/agile-bpm/agile-bpm-basic

    流程任务动态设置任务候选人

    问题:我现在有个问题,想听听各位大佬的意见,我所有的流程节点人都是不固定的,所以流程定义文件中用的都是变量,这些人可能是流程启动的时候一次性传入进去,也可能是上一节点才临时决定下一节点审批人,目前我把这些节点变量(具体的人),全部存在流程变量中(每个流程都可能都有好多人),这样做好么?有啥其他方案

    弊端:

    1、流程变量人员的设置都依靠代码,实施流程太重,性能差。

    2、流程实施对开发员对于流程引擎必须有足够的了解。整体流程实施人员学习成本太高。

    3、不利于维护,而且迭代更新的后期成本太高。

    正确做法:

    将流程人员配置化,当任务创建时,通过解析器解析出配置人员,设置到identityLink中。任务提交,还可以动态为下节点设置候选人。

    这样不需要使用流程变量。而且配置化,策略模式的去解析各种人员配置形式。可以随时修改。而且不需要编码实现。

    flowable,activiti 流程引擎与表单整合

    大多人做法: 使用url表单

    弊端

    1、分支等需要业务数据的场景会很尴尬,可能又要编码设置流程变量来解决了。

    2、流程驱动url表单去加载数据,但是数据保存又要和流程引擎耦合。

    如果url表单的数据处理器没有实现配置化,那么又要编码实施(辛苦)

    正确的做法

    url表单当然可以实现但必须注意一下几点

    1、在与其他系统整合过程中要注意事物问题

    2、url表单与流程配置化,

    3、url表单数据的处理器(保存数据的逻辑处理层)需要和流程进行配置化。

    url表单前端提供数据,提交任务后,将业务数据交给 数据处理器,

    数据处理器返回 业务id,businessKey 然后设置给流程。

    除了url表单,还可以构建一个表单引擎服务(并非activiti那种,太弱了)

    1、将业务数据抽象成统一的业务对象,

    2、使用业务对象构建,自动生成可扩展的表单

    3、为流程配置表单,将业务对象作为流程运行时的可用参数。

    这样流程提交后,做业务数据的持久化动作,并且可以在流程中使用到流程表单数据。这样做还有一个好处,流程表单的开发标准化。可以专注的为表单构建更多的可复用的表单组件。

    activiti5与flowable6选择

    参考 https://blog.csdn.net/hj7jay/article/details/68483096

    肯定选择flowable,这个会是流程高效流程引擎的未来,而且越来越注重整合方面的事情了。

    activiti流程变量获取设值

    1、可以通过实现了VariableScope接口的实体操作

    如:ExecutionEntity,TaskEntity在任务、流程监听事件中都可以拿到。建议封装BpmContext 用线程变量存储一个类似 org.activiti.engine.impl.context.Context一样的线程流程变量对象。可以直接静态方法方式拿到流程的variableScope操作流程变量。

    2、也可以在流程启动接口,任务处理接口直接将流程变量提交给流程引擎

    activiti驳回,activiti自由跳转

    现实方式

    1、重写activiti缓存,让流程定义缓存线程化

    2、任务提交前,克隆流程定义,放入线程中,动态修改流程图,让当前节点流程直接指向目标节点

    3、提交任务

    但要做一些前置的判断,比如同步中无法驳回等等

    修改流程图可以参考https://www.oschina.net/code/snippet_39770_36561

    注意:缓存必须拷贝并线程化,否则存在多线程问题,比如上面那篇文章。就只能作参考部分代码。

    文章会不定期更新其他人遇到的问题

    展开全文
  • 做工作流产品的实施有很多年了,也加了很多诸如 activiti flowable jbpm 等社区和群聊。发现很多人在走弯路,深陷泥潭不可自拔。所以写了这篇文章,旨在告诉很多走向了activiti flowable整合道路的兄弟们,切勿太...

    做工作流产品的实施有很多年了,也加了很多诸如 activiti flowable jbpm 等社区和群聊。

    发现很多人在走弯路,深陷泥潭不可自拔。

    所以写了这篇文章,旨在告诉很多走向了activiti flowable整合道路的兄弟们,切勿太过于深入整合。

    推荐下个人博文地址 doc.agilebpm.cn(这里有我多年工作流实施的经验和成果)

    流程任务动态设置任务候选人

    问题:我现在有个问题,想听听各位大佬的意见,我所有的流程节点人都是不固定的,所以流程定义文件中用的都是变量,这些人可能是流程启动的时候一次性传入进去,也可能是上一节点才临时决定下一节点审批人,目前我把这些节点变量(具体的人),全部存在流程变量中(每个流程都可能都有好多人),这样做好么?有啥其他方案

    弊端:

    流程变量人员的设置都依靠代码,实施流程太重,性能差。

    流程实施对开发员对于流程引擎必须有足够的了解。整体流程实施人员学习成本太高。

    不利于维护,而且迭代更新的后期成本太高。

    正确做法:

    将流程人员配置化,当任务创建时,通过解析器解析出配置人员,设置到identityLink中。任务提交,还可以动态为下节点设置候选人。

    这样不需要使用流程变量。而且配置化,策略模式的去解析各种人员配置形式。可以随时修改。而且不需要编码实现。

    flowable,activiti  流程引擎与表单整合

    大多人做法: 使用url表单

    弊端

    分支等需要业务数据的场景会很尴尬,可能又要编码设置流程变量来解决了。

    流程驱动url表单去加载数据,但是数据保存又要和流程引擎耦合。

    如果url表单的数据处理器没有实现配置化,那么又要编码实施(辛苦)

    正确的做法

    url表单当然可以实现但必须注意一下几点

    在与其他系统整合过程中要注意事物问题

    url表单与流程配置化,

    url表单数据的处理器(保存数据的逻辑处理层)需要和流程进行配置化。

    url表单前端提供数据,提交任务后,将业务数据交给 数据处理器,

    数据处理器返回 业务id,businessKey 然后设置给流程。

    除了url表单,还可以构建一个表单引擎服务(并非activiti那种,太弱了)

    将业务数据抽象成统一的业务对象,

    使用业务对象构建,自动生成可扩展的表单

    为流程配置表单,将业务对象作为流程运行时的可用参数。

    这样流程提交后,做业务数据的持久化动作,并且可以在流程中使用到流程表单数据。这样做还有一个好处,流程表单的开发标准化。可以专注的为表单构建更多的可复用的表单组件。

    activiti5与flowable6选择

    参考 https://blog.csdn.net/hj7jay/article/details/68483096

    肯定选择flowable,这个会是流程高效流程引擎的未来,而且越来越注重整合方面的事情了。

    activiti流程变量获取设值

    可以通过实现了VariableScope接口的实体操作流程变量。    如:ExecutionEntity,TaskEntity在任务、流程监听事件中都可以拿到。

    建议封装BpmContext 用线程变量存储一个类似 org.activiti.engine.impl.context.Context一样的线程流程变量对象。可以直接静态方法方式拿到流程的variableScope操作流程变量。

    可以在流程启动接口,任务处理接口直接将流程变量提交给流程引擎

    activiti驳回,activiti自由跳转

    现实方式

    重写activiti缓存,让流程定义缓存线程化

    任务提交前,克隆流程定义,放入线程中,动态修改流程图,让当前节点流程直接指向目标节点

    提交任务

    但驳回前要做一些前置的判断,比如同步中无法驳回等等

    修改流程图可以参考https://www.oschina.net/code/snippet_39770_36561

    注意:缓存必须拷贝并线程化,否则存在多线程问题,比如上面那篇文章。就只能作参考驳回那部分代码。

    文章会不定期更新其他人遇到的问题

    如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

    展开全文
  • 这就意味着可以将多个CompletionStage链接在一起形成一个异步任务链,前置任务执行结束之后会自动触发下一个阶段任务的执行。CompletionshiStage使用参考 这里就使用CompletionshiStage来定义一个异步数据库存储接口...
  • 瑶—基础框架搭建第一天:封装单表增删改查、唯一性校验概述模块介绍1、Controller2、Service3、Mapper4、DTO以上只是工作中使用的一部分,如果有问题或者建议欢迎各位老铁指出,...](https://gitee.com/yao_2018/yao-flowable/tree/master)...
  • Spring Data JPA - 参考文档

    千次阅读 2018-10-15 00:04:42
    Spring Data JPA - 参考文档 OliverGierke Thomas DarimontChristoph StroblMark PaluchJay Bryant版本2.1.0.RELEASE,2018-09-21 ©2008-2018原作者。   本文档的副本可供您自己使用并分发给他人,前提是您...
  • 上一篇博客【SpringBoot整合Flowable工作流-2(代码整合) 】介绍代码整合部分。 这篇博客主要介绍 Flowable 的全局事件监听器,并且基于事件监听器实现业务的通知等业务。 2. 代码实现 2.1 实现 ...

空空如也

空空如也

1
收藏数 17
精华内容 6
关键字:

flowable前置处理器

友情链接: picPWM.zip