为什么80%的码农都做不了架构师?>>>
Activiti中,任务名是支持JUEL表达式的,但是当任务执行完毕保存到流程历史表中时,这里的活动名又不支持表达式了,他会把表达式字符串保存到表中,这个说来应该是Bug。
能解决么?下一步,就是研究Activiti的代码了,看看能不能找到相应的扩展点,解决这个问题。
经过研究,找到了扩展点,开发起来还是比较方便的,下面进行详细描述,注意,本文的开发基于Activiti5.15.1版本,大体扫了下代码,更新的5.17版本也有这个问题,但未经过测试。
Activiti中流程的历史信息保存在ACT_HI_ACTINST表中,对于任务执行完毕时保存ACT_HI_ACTINST表的代码,在DefaultHistoryManager类的 recordActivityStart方法中,所以我们只要想办法继承这个类,然后覆写这个方法即可,而 DefaultHistoryManager的创建,是在DefaultHistoryManagerSessionFactory中,而 DefaultHistoryManagerSessionFactory的初始化,是在ProcessEngineConfigurationImpl 中的initSessionFactories方法,找到这里,思路已经非常清晰了,需要写的代码没有多少。
一、扩展 ProcessEngineConfigurationImpl,如果使用Spring集成的话,继承 SpringProcessEngineConfiguration类,覆写initSessionFactories方法,在该方法中调用 addSessionFactory方法添加新的自定义DefaultHistoryManagerSessionFactory;
二、扩展DefaultHistoryManagerSessionFactory,覆写openSession方法,在该方法中创建新的DefaultHistoryManager;
三、扩展DefaultHistoryManager,覆写recordActivityStart方法,这里的关键是获取表达式的解析器,然后解析即可;
具体代码如下所示:
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 {
public void recordActivityStart(ExecutionEntity executionEntity) {
if(isHistoryLevelAtLeast(HistoryLevel.ACTIVITY)) {
if(executionEntity.getActivity() != null) {
IdGenerator idGenerator = Context.getProcessEngineConfiguration().getIdGenerator();
String processDefinitionId = executionEntity.getProcessDefinitionId();
String processInstanceId = executionEntity.getProcessInstanceId();
String executionId = executionEntity.getId();
HistoricActivityInstanceEntity historicActivityInstance = new HistoricActivityInstanceEntity();
historicActivityInstance.setId(idGenerator.getNextId());
historicActivityInstance.setProcessDefinitionId(processDefinitionId);
historicActivityInstance.setProcessInstanceId(processInstanceId);
historicActivityInstance.setExecutionId(executionId);
historicActivityInstance.setActivityId(executionEntity.getActivityId());
ExpressionManager expressionManager = Context.getProcessEngineConfiguration().getExpressionManager();
Expression exp = expressionManager.createExpression((String) executionEntity.getActivity().getProperty("name"));
historicActivityInstance.setActivityName((String)exp.getValue(executionEntity));
historicActivityInstance.setActivityType((String) executionEntity.getActivity().getProperty("type"));
historicActivityInstance.setStartTime(Context.getProcessEngineConfiguration().getClock().getCurrentTime());
// Inherit tenant id (if applicable)
if (executionEntity.getTenantId() != null) {
historicActivityInstance.setTenantId(executionEntity.getTenantId());
}
getDbSqlSession().insert(historicActivityInstance);
}
}
}
}