文档章节

Activiti中的流程历史保存流程发起人的方法

李玉珏
 李玉珏
发布于 2015/02/28 15:25
字数 983
阅读 5605
收藏 4
点赞 0
评论 0

        Activiti中流程的历史信息保存在ACT_HI_ACTINST表中,流程历史信息保存在ACT_HI_PROCINST表中,我们可以通过API或者直接写SQL进行查询,但是这里面并没有流程发起人的信息,流程发起人信息有的时候还是非常必要的,比如查询某人发起的流程或者做相关的统计等。

        鉴于ACT_HI_ACTINST中保存了流程的活动历史信息,我们还是想在这个表上做文章,但是这个表中并没有发起人等相关的字段,这时候,我们发现,当一个流程刚发起时,ACT_TYPE_为startEvent,这时ASSIGNEE_为空,如果我们能借用这个字段,保存申请人,查询起来代码还是比较优雅的,虽然这个字段本身的含义不是申请人。

        另外,ACT_HI_PROCINST表中还有一个START_USER_ID_字段,但是默认为空。通过上述两种保存流程发起人的方式,在不同的场景中都能够通过简单的方式查询到流程的发起人信息。

        下一步,就是研究Activiti的代码了,看看能不能找到相应的扩展点,解决这个问题。

        经过研究,找到了扩展点,开发起来还是比较方便的,下面进行详细描述,注意,本文的开发基于Activiti5.15.1版本,大体扫了下代码,更新的5.17版本应该也兼容,但未经过测试。

        对于流程发起时保存ACT_HI_ACTINST表和ACT_HI_PROCINST表的代码,在DefaultHistoryManager类的recordProcessInstanceStart方法中,所以我们只要想办法继承这个类,然后覆写这个方法即可,而DefaultHistoryManager的创建,是在DefaultHistoryManagerSessionFactory中,而DefaultHistoryManagerSessionFactory的初始化,是在ProcessEngineConfigurationImpl中的initSessionFactories方法,找到这里,思路已经非常清晰了,需要写的代码没有多少。

        另外,还需要注意一点,Activiti中有一个线程局部变量,保存着线程上下文有关的用户信息,为Authentication中的authenticatedUserIdThreadLocal,并且该类提供相关的API进行赋值和取值,因此我们需要在流程发起之前设置该局部变量。

        一、扩展ProcessEngineConfigurationImpl,如果使用Spring集成的话,继承SpringProcessEngineConfiguration类,覆写initSessionFactories方法,在该方法中调用addSessionFactory方法添加新的自定义DefaultHistoryManagerSessionFactory;

        二、扩展DefaultHistoryManagerSessionFactory,覆写openSession方法,在该方法中创建新的DefaultHistoryManager;

        三、扩展DefaultHistoryManager,覆写recordProcessInstanceStart方法,在该方法中为assign字段赋值即可,至于当前的流程发起人获取方法,可以调用Authentication的API获取;

    具体代码如下所示:

import org.activiti.spring.SpringProcessEngineConfiguration;

public class ProcessEngineConfiguration extends SpringProcessEngineConfiguration {

    @Override
    protected void initSessionFactories() {
        super.initSessionFactories();
        super.addSessionFactory(new ProcessHistoryManagerSessionFactory());
    }
}

    

import org.activiti.engine.impl.interceptor.Session;
import org.activiti.engine.impl.persistence.DefaultHistoryManagerSessionFactory;

public class ProcessHistoryManagerSessionFactory extends DefaultHistoryManagerSessionFactory {

    @Override
    public Session openSession() {
        return new ProcessHistoryManager();
    }
}

    

public class ProcessHistoryManager extends DefaultHistoryManager {
    @Override
    public void recordProcessInstanceStart(ExecutionEntity processInstance) {
        if(isHistoryLevelAtLeast(HistoryLevel.ACTIVITY)) {
          HistoricProcessInstanceEntity historicProcessInstance = new HistoricProcessInstanceEntity(processInstance);
          getDbSqlSession().insert(historicProcessInstance);
      
          IdGenerator idGenerator = Context.getProcessEngineConfiguration().getIdGenerator();
          
          String processDefinitionId = processInstance.getProcessDefinitionId();
          String processInstanceId = processInstance.getProcessInstanceId();
          String executionId = processInstance.getId();
      
          HistoricActivityInstanceEntity historicActivityInstance = new HistoricActivityInstanceEntity();
          historicActivityInstance.setId(idGenerator.getNextId());
          historicActivityInstance.setProcessDefinitionId(processDefinitionId);
          historicActivityInstance.setProcessInstanceId(processInstanceId);
          historicActivityInstance.setExecutionId(executionId);
          historicActivityInstance.setActivityId(processInstance.getActivityId());
          historicActivityInstance.setActivityName((String) processInstance.getActivity().getProperty("name"));
          historicActivityInstance.setActivityType((String) processInstance.getActivity().getProperty("type"));
          Date now = Context.getProcessEngineConfiguration().getClock().getCurrentTime();
          historicActivityInstance.setStartTime(now);
          
          if (processInstance.getTenantId() != null) {
              historicActivityInstance.setTenantId(processInstance.getTenantId());
          }
          //通过Authentication.getAuthenticatedUserId()获取当前线程绑定的用户ID。
          historicActivityInstance.setAssignee(Authentication.getAuthenticatedUserId());
          
          getDbSqlSession().insert(historicActivityInstance);
        }      
    }
}

    Activiti在HistoricProcessInstanceEntity的构造器中已经通过Authentication获取了线程绑定用户ID。因此,我们只需要在调用runtimeService的startProcessInstance的相关方法之前赋值即可,赋值方法有两种:

identityService.setAuthenticatedUserId();//调用官方的开放API;
Authentication.setAuthenticatedUserId();//直接调用底层实现;

 

© 著作权归作者所有

共有 人打赏支持
李玉珏

李玉珏

粉丝 262
博文 57
码字总数 92143
作品 0
沈阳
技术主管
activiti参考5-历史任务

一、activiti的历史任务是单独的表来储存,表之间没有任何外间关联,这些表包括: 1,ACTHIACTINST 历史流程的运行状况记录 2,ACTHIATTACHMENT 3,ACTHICOMMENT 流程评论 4,ACTHIDETAIL流程...

安世博 ⋅ 2014/07/09 ⋅ 0

activiti学习笔记3-用户与用户组

(本博客都是纯文本手工代码,错误难免,需要在eclipse中自己调整错误代码) activiti默认建立用户表,默认的用户表可以构建简单的用户管理功能。 一、表结构 acitiviti建立了默认用户表: ...

安世博 ⋅ 2014/06/25 ⋅ 2

让Activiti记录变量历史信息

可能你在苦恼这个问题,因为在跟踪已结束流程的时候需要获取流程办理中设置的变量值(可以分析每个节点办理的详细状态),今天我们就来探索一下如何实现。 1.Activiti表结构设计 Activiti的表...

wangrikui ⋅ 2015/09/15 ⋅ 0

activiti 表结构讲解

可能你在苦恼这个问题,因为在跟踪已结束流程的时候需要获取流程办理中设置的变量值(可以分析每个节点办理的详细状态),今天我们就来探索一下如何实现。 1.Activiti表结构设计 Activiti的表...

java1990 ⋅ 2015/08/06 ⋅ 0

Activiti流程历史中活动名支持JUEL表达式的方法

Activiti中,任务名是支持JUEL表达式的,但是当任务执行完毕保存到流程历史表中时,这里的活动名又不支持表达式了,他会把表达式字符串保存到表中,这个说来应该是Bug。 能解决么?下一步,就...

李玉珏 ⋅ 2015/03/02 ⋅ 0

activiti开发笔记

actgebytearray 多个对1个 actredeployment 数据库说明: ACTRE* RE 表示 repository . 这个前缀表包含了流程定义 和流程静态资源(图片,规则等等) ACTRU* RU表示 runtime 这些运行时的表,...

之渊 ⋅ 2016/09/21 ⋅ 0

ACTIVITI5 事件监控类里的事务如何控制

activiti5 配置的事件监控类里面有数据库的处理,但是发现不能和工程的事务统一。已经配置的activiti5的事务,除了事件监控类里面的事务外,引擎其他事务和工程事务一致,但是配置的事件控制...

星忆 ⋅ 2013/07/12 ⋅ 1

Activiti 工作流学习 (三)

上一篇 Activiti 工作流学习(二) 都是在网上找的一些基本概念,引用的文档比较多比较杂,就不一一列出了。再此表示感谢。 关键对象 1. Deployment:流程部署对象,部署一个流程时创建。 2....

雷斯林 ⋅ 2016/12/10 ⋅ 0

Activiti基础教程--01(简介、代码生成Activiti的25张表、Activiti配置文件activiti.cfg.xml生成25张表、在Eclipse上安装Activiti插件)

gihub:https://github.com/changwensir/Activiti/tree/master/ActivitiDemo1 一、简介 Activiti项目是一项新的基于Apache许可的开源BPM平台,从基础开始构建,旨在提供支持新的BPMN 2.0标准,...

xiaomin0322 ⋅ 05/31 ⋅ 0

Activiti基础教程--07流程执行历史记录(历史任务、历史流程实例、历史活动)

相关代码参考gihub:https://github.com/changwensir/Activiti/tree/master/ActivitiDemo1 一、Activiti 历史任务查询 实际工作流项目中,有一个功能叫做 历史任务查询。某一次流程的执行一共...

xiaomin0322 ⋅ 05/31 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Kubeflow实战系列:利用TFJob导出分布式TensorFlow模型

介绍 本系列将介绍如何在阿里云容器服务上运行Kubeflow, 本文介绍如何使用TfJob导出分布式模型训练模型。 第一篇:阿里云上使用JupyterHub 第二篇:阿里云上小试TFJob 第三篇:利用TFJob运行...

全部原谅 ⋅ 5分钟前 ⋅ 0

007. 深入JVM学习—老年代

老年代空间的主要目的是用于存储由Eden发送来的对象,一般在经历好几次“Minor GC”还会保存下来的对象,才会被复制到老年代,这样就可以存放更多的对象,同时在老年代中执行GC的次数也相对较...

影狼 ⋅ 6分钟前 ⋅ 0

常见的一些C#开源框架或者开源项目

原:https://blog.csdn.net/qq_27825451/article/details/70666044 Json.NET http://json.codeplex.com/ Json.Net 是一个读写Json效率比较高的.Net框架.Json.Net 使得在.Net环境下使用Json更......

whoisliang ⋅ 7分钟前 ⋅ 0

设计模式基本原理

刚开始接触编程这行的时候看过设计模式,当时感觉学这些模式没有太大的用处,当时也看不太懂。但是随着慢慢接触这一行,经过一段时间的编程以后,再回过头来看设计模式,发现设计模式的确是太...

王子城 ⋅ 11分钟前 ⋅ 0

阿里云全面支持IPv6!一文揽尽4位大咖精彩演讲

摘要: 自从去年11月以来,阿里巴巴高度重视数据中心的网络改造、云产品改造、应用及网络改造等多个维度,经过半年以来的建设,阿里云已经完成了域名解析等关键产品的分析,现在阿里云已经完...

传授知识的天使 ⋅ 21分钟前 ⋅ 0

windows Android sdk 配置

1、下载Android SDK,点击安装,直接默认路径即可! 下载地址:http://developer.android.com/sdk/index.html 2、默认路径安装后,安装完成,开始配置环境变量。 3、打开计算机属性——高级系...

阿豪boy ⋅ 24分钟前 ⋅ 0

bash shell script 简明教程

User <--> bash <--> kernel shell is not kernel or part of kernel various shells: tcsh, csh, bash, ksh find the using shell: echo $SHELL find all the shells: cat /etc/shells what......

mskk ⋅ 26分钟前 ⋅ 0

Service Mesh简史

William Morgan Service Mesh是一个相当新的概念,讲它的“历史”似乎有些勉强。就目前而言,Service Mesh已经在部分企业生产环境中运行了超过18个月,它的源头可以追溯到2010年前后互联网公...

好雨云帮 ⋅ 26分钟前 ⋅ 0

10个免费的服务器监控工具

监控你的WEB服务器或者WEB主机运行是否正常与健康是非常重要的。你要确保用户始终可以打开你的网站并且网速不慢。服务器监控工具允许你收集和分析有关你的Web服务器的数据。 有许多非常好的服...

李朝强 ⋅ 39分钟前 ⋅ 0

压缩工具之zip-tar

zip 支持目录压缩。使用yum安装zip包,使用yum安装unzip包 zip 1.txt.zip 1.txt #将1.txt文件压缩,新生成的压缩文件为1.txt.zip,原文件保留 zip -r 123.zip 123/ #-r对目录操作。将123/目录...

ZHENG-JY ⋅ 39分钟前 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部