工作流引擎Activiti使用进阶!详细解析工作流框架中高级功能的使用示例

Activiti高级功能简介

Activit的高级用例,会超越BPMN 2.0流程的范畴,使用Activiti高级功能需要有Activiti开发的明确目标和足够的Activiti开发经验

监听流程解析

bpmn 2.0 xml文件需要被解析为Activiti内部模型,然后才能在Activiti引擎中运行.解析过程发生在发布流程或在内存中找不到对应流程的时候,这时会从数据库查询对应的xml

对于每个流程 ,BpmnParser类都会创建一个新的BpmnParse实例.这个实例会作为解析过程中的容器来使用

解析过程:

对于每个BPMN 2.0元素,引擎中都会有一个对应的org.activiti.engine.parse.BpmnParseHandler实例

解析器会保存一个BPMN 2.0元素与BpmnParseHandler实例的映射

默认Activiti使用BpmnParseHandler来处理所有支持的元素

同时也使用BpmnParseHandler来提供执行监听器,以支持流程历史

可以向Activiti引擎中添加自定义的org.activiti.engine.parse.BpmnParseHandler实例

经常使用的用例是把执行监听器添加到对应的环节,来处理一些事件队列.Activiti在内部就是这样进行历史处理的

要想添加这样的自定义处理器,需要为Activit增加配置:

<property> <list> <bean /> </list> </property> <property> <list> <bean /> <bean /> </list> </property>

当自定义处理器内部逻辑对处理顺序有要求时需要考虑:

配置到preBpmnParseHandlers的BpmnParseHandler实例会添加在默认处理器的前面

配置到postBpmnParseHandlers的BpmnParseHandler实例会添加在默认处理器的后面

接口- org.activiti.engine.parse.BpmnParseHandler:

public interface BpmnParseHandler { Collection<Class>? extends BaseElement>> getHandledTypes(); void parse(BpmnParse bpmnParse, BaseElement element); }

BpmnParseHandler接口中:

getHandledTypes()方法会翻译这个解析器处理的所有类型的集合,这些都是BaseElement的子类,返回集合的泛型限制也说明了这一点

也可以继承AbstractBpmnParseHandler类并重写getHandledType()方法,这样就只需要返回一个类型,而不是一个集合

这个类也包含需要默认解析处理器所需要的方法

BpmnParseHandler实例只有在解析器访问到这个方法返回的类型时才会被调用

示例:

BPMN 2.0 xml包含process元素时,就会执行executeParse方法中的逻辑

这是一个已经完成类型转换的方法,替换BpmnParseHandler接口中的parse方法

public class TestBPMNParseHandler extends AbstractBpmnParseHandler<Process> { protected Class<? extends BaseElement> getHandledType() { return Process.class; } protected void executeParse(BpmnParse bpmnParse, Process element) { .. } }

注意:

在编写自定义解析处理器时,不要使用任何解析BPMN 2.0结构的内部类,这会导致出现问题很难定义

应该实现BpmnParseHandler接口或集成内部抽象类 org.activiti.engine.impl.bpmn.parser.handler.AbstractBpmnParseHandler

也可以替换默认的BpmnParseHandler实例,把解析BPMN 2.0元素替换为解析Activiti内部模型:

<property> <list> ... </list> </property>

示例: 将所有任务强制设置为异步

public class CustomUserTaskBpmnParseHandler extends ServiceTaskParseHandler { protected void executeParse(BpmnParse bpmnParse, ServiceTask serviceTask) { // Do the regular stuff super.executeParse(bpmnParse, serviceTask); // Make always async ActivityImpl activity = findActivity(bpmnParse, serviceTask.getId()); activity.setAsync(true); } } 支持高并发的UUID的ID生成器

在高并发的场景中,默认的ID生成器可能因为无法很快的获取新ID区域而导致异常

所有流程引擎都有一个ID生成器,默认的ID生成器会在数据库划取一块ID范围,其余引擎不能使用相同范围的ID

在引擎运行期间,当默认的ID生成器发现已经越过ID范围时,就会启动一个新事务来获得新范围.在极限的情况下,高负载会导致问题

对于大部分情况,默认ID生成已经足够:

默认的org.activiti.engine.impl.db.DbIdGenerator有一个idBlockSize属性,可以配置获取ID范围的大小,这样就可以改变获取ID的行为

另一个可以选用的默认ID生成器是org.activiti.engine.impl.persistence.StrongUuidGenerator:

会在本地生成一个唯一的UUID作为所有实体的标识

因为生成UUID不需要访问数据库,所以在高并发环境下的表现比较好

默认ID生成器的性能依赖于运行硬件

将UUID生成器配置到Activiti:

<property> <bean /> </property>

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyjzwy.html