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

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

源自:http://my.oschina.net/liyuj/blog/380777


摘要  Activiti中流程的活动历史信息保存在ACT_HI_ACTINST表中,流程历史信息保存在ACT_HI_PROCINST表中,我们可以通过API或者直接写SQL进行查询,但是这里面并没有流程发起人的信息,流程发起人信息有的时候还是非常必要的,本文将提供一种方式,保存流程发起人信息,这样我们就能够查询到某人发起的流程了。

        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获取;

    具体代码如下所示:

?
1
2
3
4
5
6
7
8
9
10
import  org.activiti.spring.SpringProcessEngineConfiguration;
 
public  class  ProcessEngineConfiguration  extends  SpringProcessEngineConfiguration {
 
     @Override
     protected  void  initSessionFactories() {
         super .initSessionFactories();
         super .addSessionFactory( new  ProcessHistoryManagerSessionFactory());
     }
}

    

?
1
2
3
4
5
6
7
8
9
10
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();
     }
}

    

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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的相关方法之前赋值即可,赋值方法有两种:

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


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Activiti事件监听器获取流程发起人信息,可以通过以下方式进行操作: 1. 使用`ExecutionListener`接口:在BPMN,可以使用`executionListener`元素来监听事件。在事件触发时,可以通过`DelegateExecution`对象获取流程实例信息,包括流程发起人。 ```java import org.activiti.engine.delegate.DelegateExecution; import org.activiti.engine.delegate.ExecutionListener; public class MyExecutionListener implements ExecutionListener { @Override public void notify(DelegateExecution execution) { String initiator = (String) execution.getVariable("initiator"); // 执行你的逻辑操作 } } ``` 在BPMN配置`executionListener`元素: ```xml <process id="myProcess" name="My Process"> <!-- ... --> <startEvent id="start" name="Start"> <extensionElements> <activiti:executionListener event="start" class="com.example.MyExecutionListener" /> </extensionElements> </startEvent> <!-- ... --> </process> ``` 2. 使用任务监听器(Task Listener):如果你在流程包含了用户任务,你可以使用任务监听器来监听任务的创建事件。此时,你可以通过`DelegateTask`对象获取任务相关的信息,包括任务的创建人。 ```java import org.activiti.engine.delegate.DelegateTask; import org.activiti.engine.delegate.TaskListener; public class MyTaskListener implements TaskListener { @Override public void notify(DelegateTask task) { String initiator = task.getProcessInstance().getStartUserId(); // 执行你的逻辑操作 } } ``` 在BPMN配置任务监听器: ```xml <userTask id="task1" name="Task 1"> <extensionElements> <activiti:taskListener event="create" class="com.example.MyTaskListener" /> </extensionElements> </userTask> ``` 通过上述方式,你可以在Activiti事件监听器获取流程发起人的信息。请根据你的具体需求选择合适的监听器类型,并在相应的位置配置监听器。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值