一.前言
前面Activiti工作流的学习,说明了Activiti的基本应用,在我们开发中可以根据实际的业务参考Activiti的API去更好的理解以及巩固。我们实际的开发中我们基本上都使用spring框架进行开发,现在来说明一下Activiti工作流与spring集成,Activiti工作流与spring集成还算比较简单,可以参考Activiti的API来进行整合。
二.Activiti常用的表
---------------------------------------------部署对象和流程定义相关的表--------------------------------------------- --部署对象信息表 SELECT T.*, T.ROWID FROM ACT_RE_DEPLOYMENT T; --流程定义表 --ID_ 由KEY_ + VERSION_ + 随机生成是数组成 SELECT T.*, T.ROWID FROM ACT_RE_PROCDEF T where t.category_= '1' order by t.version_ asc ; --资源文件表 SELECT T.*, T.ROWID FROM ACT_GE_BYTEARRAY T; --主键生成策略表 SELECT T.*, T.ROWID FROM ACT_GE_PROPERTY T; ------------------------------------------流程实例、执行对象、任务------------------------------------------------ --正在执行的执行对象表 -- 执行ID_ 56 流程实例ID_ 56 流程定义ID_ _3701622B-4133-7B3D-F50F-E14B4F21E847:1:55 正在运行的任务定义ID_ 【可变】 USERTASKE736BEF8-4133-7B3D-F510-7B2DE7BEA8C6 SELECT T.*, T.ROWID FROM ACT_RU_EXECUTION T; --流程实例历史表 开始信息 --历史流程定义ID_ 56 流程S实例ID_ 56 业务KEY_10000001 流程定义ID_ _3701622B-4133-7B3D-F50F-E14B4F21E847:1:55 开始任务节点ID_ STARTEVENT52B3145F-C133-7B3D-F50F-E6D48BA60EAE SELECT T.*, T.ROWID FROM ACT_HI_PROCINST T; --正在执行的任务对象表 --任务ID_ 68 执行ID_ 56 流程实例ID_ 56 流程定义ID_ _3701622B-4133-7B3D-F50F-E14B4F21E847:1:55 任务节点ID_ USERTASKE736BEF8-4133-7B3D-F510-7B2DE7BEA8C6 SELECT T.*, T.ROWID FROM ACT_RU_TASK T; --历史任务流程实例信息 --历史任务ID_ 68 流程实例ID_ 56 执行实例ID_ 56 流程定义ID_ _3701622B-4133-7B3D-F50F-E14B4F21E847:1:55 任务节点ID_ USERTASKE736BEF8-4133-7B3D-F510-7B2DE7BEA8C6 表单KEY_ /PAGES/HOLIDAY/HOLIDAYMANAGE/HOLIDAYFORMHANDLE.JSP --历史任务ID_ 74 流程实例ID_ 56 执行实例ID_ 56 流程定义ID_ _3701622B-4133-7B3D-F50F-E14B4F21E847:1:55 任务节点ID_ USERTASK04A84BE1-1133-7B3D-F511-1D0B7BB0A668 表单KEY_ /PAGES/HOLIDAY/HOLIDAYMANAGE/HOLIDAYFORMVIEW.JSP SELECT T.*, T.ROWID FROM ACT_HI_TASKINST T; --所有活动节点历史任务表 --历史任务ID_58 流程定义ID_ _3701622B-4133-7B3D-F50F-E14B4F21E847:1:55 流程实例ID_ 56 流程执行ID_ 56 任务节点ID_ STARTEVENT52B3145F-C133-7B3D-F50F-E6D48BA60EAE --历史任务ID_67 流程定义ID_ _3701622B-4133-7B3D-F50F-E14B4F21E847:1:55 流程实例ID_ 56 流程执行ID_ 56 任务节点ID_ USERTASKE736BEF8-4133-7B3D-F510-7B2DE7BEA8C6 任务ID_ 68 --历史任务ID_73 流程定义ID_ _3701622B-4133-7B3D-F50F-E14B4F21E847:1:55 流程实例ID_ 56 流程执行ID_ 56 任务节点ID_ USERTASK04A84BE1-1133-7B3D-F511-1D0B7BB0A668 任务ID_ 74 SELECT T.*, T.ROWID FROM ACT_HI_ACTINST T; ----------------------------------------流程变量信息-------------------------------------------------- --正在执行的流程变量信息 SELECT T.*, T.ROWID FROM ACT_RU_VARIABLE T; --历史流程变量信息 存放历史表单重要信息 --流程实例ID_ 56 执行实例ID_ 56 任务ID_ SELECT T.*, T.ROWID FROM ACT_HI_VARINST T; -------------------------------------------历史意见信息----------------------------------------------- --历史审批意见表 --任务ID_ 68 流程定义ID_ 56 SELECT T.*, T.ROWID FROM ACT_HI_COMMENT T; -----------------------------------------节点参与者信息------------------------------------------------- --任务办理人表(个人任务、组任务) SELECT T.*, T.ROWID FROM ACT_RU_IDENTITYLINK T; --历史任务办理人表(个人任务、组任务) SELECT T.*, T.ROWID FROM ACT_HI_IDENTITYLINK T; --临时对象 SELECT T.*, T.ROWID FROM EA_IST.IST_APPR_BUSI_DATA T |
三.Activiti与spring整合xml配置文件
向spring配置文件中,添加一个spring-workflow2-activiti.xml配置文件,里面如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd"> <!--工作流引擎配置 --> <bean id="processEngineConfiguration" class="com.shine.workflow2.spring.ShineSpringProcessEngineConfiguration"> <property name="dataSource" ref="dataSource" /> <property name="transactionManager" ref="transactionManager" /> <property name="databaseSchemaUpdate" value="false" /> <property name="jobExecutorActivate" value="false" /> <!-- 组织机构适配 --> <property name="organizationConnector" ref="organizationAdapter" /> </bean> <!-- 组织机构适配实现 --> <bean id="organizationAdapter" class="com.shine.workflow2.organization.impl.OrganizationAdapter" /> <!--工作流引擎 --> <bean id="processEngine" class="com.shine.workflow2.spring.ShineProcessEngineFactoryBean"> <property name="processEngineConfiguration" ref="processEngineConfiguration" /> </bean> <!--扩展服务 --> <bean id="processDefinitionService" factory-bean="processEngine" factory-method="getProcessDefinitionService" /> <bean id="processLogService" factory-bean="processEngine" factory-method="getProcessLogService" /> <bean id="processManagementService" factory-bean="processEngine" factory-method="getProcessManagementService" /> <!--原生服务 --> <bean id="repositoryService" factory-bean="processEngine" factory-method="getRepositoryService" /> <bean id="runtimeService" factory-bean="processEngine" factory-method="getRuntimeService" /> <bean id="taskService" factory-bean="processEngine" factory-method="getTaskService" /> <bean id="historyService" factory-bean="processEngine" factory-method="getHistoryService" /> <bean id="managementService" factory-bean="processEngine" factory-method="getManagementService" /> <bean id="formService" factory-bean="processEngine" factory-method="getFormService" /> <bean id="identityService" factory-bean="processEngine" factory-method="getIdentityService" /> </beans>
四.Activiti工作流常用service
1.BaseProcessService
/** * */ package com.shine.eosp.workflow2.common.process; import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity; import org.activiti.engine.impl.pvm.PvmActivity; import org.activiti.engine.impl.pvm.process.ActivityImpl; import org.activiti.engine.impl.task.TaskDefinition; import org.activiti.engine.repository.ProcessDefinition; import org.activiti.engine.runtime.Execution; import org.activiti.engine.runtime.ProcessInstance; import org.activiti.engine.task.Task; import com.shine.workflow2.exception.WorkflowException; /** * * 类说明: 常用工作流核心操作封装 . * *
* 修改日期 修改人 修改原因 * 2016-6-2 hongwz 新建 *
*/ public interface BaseProcessService { /** * 方法说明 : 根据流程定义Key查询最新流程定义. * * @param processDefinitionKey * @throws WorkflowException */ public ProcessDefinition findLatestProcessDefinitionByPrcDefKey(String processDefinitionKey) throws WorkflowException; /** * 方法说明 : 根据流程定义Id查询流程定义. * * @param processDefinitionId 流程定义Id * @throws WorkflowException */ public ProcessDefinitionEntity findProcessDefinitionEntityByProcDefId(String processDefinitionId) throws WorkflowException; /** * * 方法说明 : 根据流程实例Id查询流程实例. * * @param processInstanceId 流程实例Id * @return * @throws WorkflowException */ public ProcessInstance findProcessInstanceByProcInst(String processInstanceId) throws WorkflowException; /** * 根据流程实例Id查询流程实例. * * @param processInstanceId * @throws WorkflowException */ public Execution findExecutionByProcInst(String processInstanceId) throws WorkflowException; /** * 方法说明 : 根据流程实例Id查询任务. * * @param processInstanceId 流程实例Id * @throws WorkflowException */ public Task findTaskByProcInstId(String processInstanceId) throws WorkflowException; /** * 方法说明 : 根据实例Id查询任务. * * @param executionId 实例Id * @throws WorkflowException */ public Task findTaskByExecutionId(String executionId) throws WorkflowException; /** * 方法说明 : 根据活动节点查询任务定义. * * @param activityImpl 活动节点 * @throws WorkflowException */ public TaskDefinition findTaskDefinitionByActivityImpl(ActivityImpl activityImpl) throws WorkflowException; /** * 方法说明 : 查询上一个节点. * * @param activityImpl 活动节点 * @param activityId 当前活动节点ID * @param elString * @throws ShineException */ public TaskDefinition beforeTaskDefinition(ActivityImpl activityImpl,String activityId, String elString) throws WorkflowException; /** * 方法说明 : 查询下一个节点. * * @param activityImpl 活动节点 * @param activityId 当前活动节点ID * @param elString * @throws ShineException */ public TaskDefinition nextTaskDefinition(ActivityImpl activityImpl,String activityId, String elString) throws WorkflowException; /** * 方法说明: 根据活动节点、活动线路查询线路的连接线. * * @throws WorkflowException */ public PvmActivity findPvmActivity(ActivityImpl activityImpl, String transitions) throws WorkflowException; /** * 方法说明 :根据流程定义Id查询任务定义 * * @param processDefinitionId 流程定义Id * @return * @throws WorkflowException */ public TaskDefinition findTaskDefinition(String processDefinitionId) throws WorkflowException; /** * 方法说明 : 添加任务意见. * * @param taskId 任务Id * @param processInstanceId 流程实例Id * @param comment 意见 * @throws WorkflowException */ public void addTaskComment(String taskId, String processInstanceId, String comment) throws WorkflowException; /** * 方法说明 : 拾取任务. * * @param taskId 任务Id * @param operator 办理人 * @throws WorkflowException */ public void claimTask(String taskId, String operator) throws WorkflowException; /** * 方法说明 : 根据流程定义Id查询最新流程定义. * * @param processDefinitionId 流程定义Id * @return * @throws WorkflowException */ public ProcessDefinition findProcessDefinitionByPrcDefId(String processDefinitionId) throws WorkflowException; } |
2.BaseProcessServiceImpl
/** * */ package com.shine.eosp.workflow2.common.process; import java.util.Iterator; import java.util.List; import org.activiti.engine.HistoryService; import org.activiti.engine.RepositoryService; import org.activiti.engine.RuntimeService; import org.activiti.engine.TaskService; import org.activiti.engine.impl.RepositoryServiceImpl; import org.activiti.engine.impl.bpmn.behavior.UserTaskActivityBehavior; import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity; import org.activiti.engine.impl.pvm.PvmActivity; import org.activiti.engine.impl.pvm.PvmTransition; import org.activiti.engine.impl.pvm.process.ActivityImpl; import org.activiti.engine.impl.task.TaskDefinition; import org.activiti.engine.repository.ProcessDefinition; import org.activiti.engine.runtime.Execution; import org.activiti.engine.runtime.ProcessInstance; import org.activiti.engine.task.Task; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import com.shine.util.CollectionUtil; import com.shine.workflow2.exception.WorkflowException; /** * * 类说明: 常用工作流核心操作封装 . * *
* 修改日期 修改人 修改原因 * 2016-6-2 hongwz 新建 *
*/ public class BaseProcessServiceImpl implements BaseProcessService { /** * log. */ private static Logger logger = LoggerFactory.getLogger(BaseProcessServiceImpl. class ); @Autowired private RepositoryService repositoryService; @Autowired private RuntimeService runtimeService; @Autowired private TaskService taskService; @Autowired private HistoryService historyService; /** * 方法说明 : 根据流程定义Key查询最新流程定义. * * @param processDefinitionKey 流程定义Key * @return * @throws WorkflowException */ @Override public ProcessDefinition findLatestProcessDefinitionByPrcDefKey(String processDefinitionKey) throws WorkflowException{ ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery() .processDefinitionKey(processDefinitionKey) .latestVersion() .singleResult(); return processDefinition; } /** * 方法说明 : 根据流程定义Id查询最新流程定义. * * @param processDefinitionId 流程定义Id * @return * @throws WorkflowException */ @Override public ProcessDefinition findProcessDefinitionByPrcDefId(String processDefinitionId) throws WorkflowException{ ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery() .processDefinitionId(processDefinitionId) .orderByProcessDefinitionVersion() .desc() .singleResult(); return processDefinition; } /** * 方法说明 : 根据流程定义Id查询流程定义. * * @param processDefinitionId 流程定义Id * @return * @throws WorkflowException */ @Override public ProcessDefinitionEntity findProcessDefinitionEntityByProcDefId(String processDefinitionId) throws WorkflowException{ ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService) .getDeployedProcessDefinition(processDefinitionId); return processDefinitionEntity; } /** * * 方法说明 : 根据流程实例Id查询流程实例. * * @param processInstanceId 流程实例Id * @return * @throws WorkflowException */ @Override public ProcessInstance findProcessInstanceByProcInst(String processInstanceId) throws WorkflowException{ return runtimeService.createProcessInstanceQuery() .processInstanceId(processInstanceId) .singleResult(); } /** * 根据流程实例Id查询流程实例. * * @param processInstanceId * @return * @throws WorkflowException */ @Override public Execution findExecutionByProcInst(String processInstanceId) throws WorkflowException{ return runtimeService.createExecutionQuery().processInstanceId(processInstanceId).singleResult(); } /** * 方法说明 : 根据流程实例Id查询任务. * * @param processInstanceId 流程实例Id * @return * @throws WorkflowException */ @Override public Task findTaskByProcInstId(String processInstanceId) throws WorkflowException{ return taskService.createTaskQuery().processInstanceId(processInstanceId).singleResult(); } /** * 方法说明 : 根据实例Id查询任务. * * @param executionId 实例Id * @return * @throws WorkflowException */ @Override public Task findTaskByExecutionId(String executionId) throws WorkflowException{ return taskService.createTaskQuery().executionId(executionId).singleResult(); } /** * 方法说明 : 根据活动节点查询任务定义. * * @param activityImpl 活动节点 * @return * @throws WorkflowException */ @Override public TaskDefinition findTaskDefinitionByActivityImpl(ActivityImpl activityImpl) throws WorkflowException{ return ((UserTaskActivityBehavior)activityImpl.getActivityBehavior()).getTaskDefinition(); } /** * 方法说明 : 查询上一个节点. * * @param activityImpl 活动节点 * @param activityId 当前活动节点ID * @param elString * @return * @throws ShineException */ @Override public TaskDefinition beforeTaskDefinition(ActivityImpl activityImpl,String activityId, String elString) throws WorkflowException { if ( "userTask" .equals(activityImpl.getProperty( "type" )) && !activityId.equals(activityImpl.getId())){ TaskDefinition taskDefinition = null ; if (activityImpl != null ){ taskDefinition = findTaskDefinitionByActivityImpl(activityImpl); } return taskDefinition; } else { List<PvmTransition> inTransitions = activityImpl.getIncomingTransitions(); //通过活动节点查询所有线路 if (!CollectionUtil.isEmpty(inTransitions)){ List<PvmTransition> inTransitionsTemp = null ; for (PvmTransition tr:inTransitions){ PvmActivity ac = tr.getSource(); //获取线路的前节点 if ( "exclusiveGateway" .equals(ac.getProperty( "type" ))){ inTransitionsTemp = ac.getIncomingTransitions(); if (inTransitionsTemp.size() == 1 ){ return beforeTaskDefinition((ActivityImpl)inTransitionsTemp.get( 0 ).getSource(), activityId, elString); } else if (inTransitionsTemp.size() > 1 ){ for (PvmTransition tr1 : inTransitionsTemp){ Object s = tr1.getProperty( "conditionText" ); if (elString.equals(StringUtils.replacePattern(StringUtils.trim(s.toString()), " " , "" ))){ return beforeTaskDefinition((ActivityImpl)tr1.getSource(), activityId, elString); } } } } } } return null ; } } /** * 方法说明 : 查询下一个节点. * * @param activityImpl 活动节点 * @param activityId 当前活动节点ID * @param elString * @return * @throws ShineException */ @Override public TaskDefinition nextTaskDefinition(ActivityImpl activityImpl,String activityId, String elString) throws WorkflowException { if ( "userTask" .equals(activityImpl.getProperty( "type" )) && !activityId.equals(activityImpl.getId())){ TaskDefinition taskDefinition = null ; if (activityImpl != null ){ taskDefinition = findTaskDefinitionByActivityImpl(activityImpl); } return taskDefinition; } else { List<PvmTransition> outTransitions = activityImpl.getOutgoingTransitions(); //通过活动节点查询所有线路 if (!CollectionUtil.isEmpty(outTransitions)){ List<PvmTransition> outTransitionsTemp = null ; for (PvmTransition tr:outTransitions){ PvmActivity ac = tr.getDestination(); //获取线路的终点节点 if ( "exclusiveGateway" .equals(ac.getProperty( "type" ))){ outTransitionsTemp = ac.getOutgoingTransitions(); if (outTransitionsTemp.size() == 1 ){ return nextTaskDefinition((ActivityImpl)outTransitionsTemp.get( 0 ).getDestination(), activityId, elString); } else if (outTransitionsTemp.size() > 1 ){ for (PvmTransition tr1 : outTransitionsTemp){ Object s = tr1.getProperty( "conditionText" ); if (s != null && elString.equals(StringUtils.replacePattern(StringUtils.trim(s.toString()), " " , "" ))){ return nextTaskDefinition((ActivityImpl)tr1.getDestination(), activityId, elString); } } } } else if ( "userTask" .equals(ac.getProperty( "type" ))){ return findTaskDefinitionByActivityImpl((ActivityImpl)ac); } else if ( "startEvent" .equals(ac.getProperty( "type" ))){ return findTaskDefinitionByActivityImpl((ActivityImpl)ac); } else { logger.info(ac.getProperty( "type" ).toString()); } } } return null ; } } /** * 方法说明: 根据活动节点、活动线路查询线路的连接线. * * @return * @throws WorkflowException */ @SuppressWarnings ( "rawtypes" ) @Override public PvmActivity findPvmActivity(ActivityImpl activityImpl, String transitions) throws WorkflowException{ PvmActivity activity = null ; List<PvmTransition> pvmTransitions = activityImpl.getOutgoingTransitions(); //获取所有线路 for (Iterator iterator = pvmTransitions.iterator(); iterator.hasNext();) { PvmTransition pvmTransition = (PvmTransition) iterator.next(); PvmActivity pvmActivity = pvmTransition.getDestination(); //获取下一个任务节点 String transitionsVal = (String) pvmActivity.getProperty( "name" ); if (transitions.equals(transitionsVal)){ activity = pvmActivity; break ; } } return activity; } /** * 方法说明 :根据流程定义Id查询任务定义 * * @param processDefinitionId 流程定义Id * @return * @throws WorkflowException */ @Override public TaskDefinition findTaskDefinition(String processDefinitionId) throws WorkflowException{ //获取流程定义 ProcessDefinitionEntity processDefinitionEntity = findProcessDefinitionEntityByProcDefId(processDefinitionId); TaskDefinition tdf = null ; if (processDefinitionEntity != null ){ List<ActivityImpl> activityImpls = processDefinitionEntity.getActivities(); //获取所有活动的节点 for ( int i = activityImpls.size() - 1 ; i > 0 ; i-- ){ ActivityImpl activityImpl = activityImpls.get(i); String startEventType = (String) activityImpl.getProperty( "type" ); if ( "startEvent" .equals(startEventType)){ tdf = nextTaskDefinition(activityImpl, activityImpl.getId(), null ); } } } return tdf; } /** * 方法说明 : 添加任务意见. * * @param taskId 任务Id * @param processInstanceId 流程实例Id * @param comment 意见 * @throws WorkflowException */ @Override public void addTaskComment(String taskId,String processInstanceId,String comment) throws WorkflowException{ taskService.addComment(taskId, processInstanceId, comment); } /** * 方法说明 : 拾取任务. * * @param taskId 任务Id * @param operator 办理人 * @throws WorkflowException */ @Override public void claimTask(String taskId,String operator) throws WorkflowException{ taskService.claim(taskId, operator); } } |
写博客是为了记住自己容易忘记的东西,另外也是对自己工作的总结,文章可以转载,无需版权。希望尽自己的努力,做到更好,大家一起努力进步!
如果有什么问题,欢迎大家一起探讨,代码如有问题,欢迎各位大神指正!
原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/15470.html