Activiti实战心得

Activiti的作用可以说就是:按照你既定的流程图,进行业务的流转。如果根据数据库独自设计一套关于业务的工作流,也是可以实现的,但耗费成本比较高,扩展性没有Activiti好。Activiti可以用在OA中的工作流,合同以及项目的流转等一些流程性的业务中。只需要画好流程图和流程中流转的条件,就可以很好的控制业务节点的流转。

Activiti需要搭配一些业务表进行使用,可以很好的记录和控制节点按照预期方向进行流转。记录每次流转传递的参数,可以在发生生产问题时,查明当时的业务流转哪个环节出现了问题,光靠打印日志还远远不够。

Activiti结合现有框架不赘述,结合实际情况进行整合即可。

 

1.画流程图

按照实际业务需要绘制流程图,画完的流程图是个bpmn文件,png图片只是用来浏览大致流程的图片,部署流程时只需要bpmn文件。我写了个demo,流程是这个样子的。

2.部署流程

有的教程中直接就说 runtimeService.startProcessInstanceByKey启动流程,这样肯定会报no processes deployed with key的问题,因为在Activiti的表中没有这个流程,所以在启动之前肯定要先部署画好的流程图。

部署的实质上就是调用repositoryService.createDeployment().addBytes().deploy() 进行部署新的流程,部署好的流程图文件会保存在act_ge_bytearray表中。因为存在act_ge_bytearray表中是BLOB文件,所以直接插入SQL会有一定的问题。我写了一个后台管理的页面,上传bpmn文件进行部署,这样就会避免发生BLOB文件插入表的问题。通过repositoryService.getBpmnModel 方法获取所有流程节点的信息,然后保存在自己建立的表中,这样在实际业务中可以灵活使用。

 

3.启动流程

启动流程的实质上就是

//传递的参数集合
Map<String, Object> map=new HashMap<String,Object>();

ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
// 取运行时服务
RuntimeService runtimeService = processEngine.getRuntimeService();
// 启动流程
ProcessInstance process = runtimeService.startProcessInstanceByKey(processCode, map);

这样就启动了一个流程实例,通过 process.getProcessInstanceId() 获取流程实例的processInstanceId然后保存在自己的业务表中就可以对应到这一个流程了。

 

4.节点流转

上面启动了一个流程实例ID,并且取到了processInstanceId。正在运转中的流程会保存在act_ru_task表中,根据processInstanceId查询act_ru_task表中的ID_。因为每流转一次节点,act_ru_task的ID_都会变,但processInstanceId是不会变的。节点流转其实就是 processEngine.getTaskService().complete(ID_,map) (map为转递参数,即在画流程图时定义的Main config中condition的参数条件)

如果想要从当前节点流向下一个节点,就把当前的ID_和流转下一个节点的条件参数传进来就可以按照既定的流程进行业务的流转。如果下一个节点经过一个排他网关,就要格外注意参数的传递,保存好节点流转时传递参数的报文,防止有人写了bug出来搞事情。

其实节点流转就跟安装程序一样,下一步next下一步next。

最后流转到结束事件整个流程执行完毕,act_ru_task表中的数据也会清除。act_hi_taskinst表中正在运行的流程,END_TIME_字段会是空的,执行完的流程这个字段才会有数据。

其实表中间带hi的都是记录历史信息的。

 

5.监听器

如果存在跳过节点的情况,比如我的流程图中,饿了要吃饭,正常应该流转到 开始思考吃什么,但是有某种条件下需要跳过该节点,这时候就在Skip expression中添加 ${execution.getVariable('noThink') == 1 } (noThink==1是我自己的流程参数),执行complete方法传参时传入就行。

还要在Listeners中设置监听器,不然跳过节点功能不好使,监听器自己写的,代码如下:

public class SkipListenner implements ExecutionListener {

	private static final long serialVersionUID = 1L;

	@Override
	public void notify(DelegateExecution execution) {
		// 获取流程变量
		Map<String, Object> variables = execution.getVariables();
		// 开启支持跳过表达式
		variables.put("_ACTIVITI_SKIP_EXPRESSION_ENABLED", true);
		// 将修改同步到流程中
		execution.setTransientVariables(variables);
	}

}

重点其实就是 _ACTIVITI_SKIP_EXPRESSION_ENABLED 参数。

设置Listeners就是这个样子的

 

 

5.注意事项

  • 注意Activiti表和业务表的结合使用,一个流程对应一个processInstanceId。
  • 记录好流程流转时的参数传递,以及存表时的事务一致性问题。(都是泪)
  • 如果流程会有修改的可能,尽量把部署流程做成后台配置的那种,删除已发布的流程其实就是processEngine.getRepositoryService().deleteDeployment(deploymentId, true); deploymentId就是act_ge_bytearray表的DEPLOYMENT_ID_ 。 
  • 暂时没了,想起来再说。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值