activiti流程文件细解

合集下载

Activiti流程图部署及流程图部分操作

Activiti流程图部署及流程图部分操作

Activiti流程图部署及流程图部分操作 流程图部署有两种⽅式,⼀种是通过classpath,另⼀种是通过zip⽂件 通过classpath⽅式如下public void deploymentProcessDefinition_classpath(){Deployment deployment = processEngine.getRepositoryService()//与流程定义和部署相关的service.createDeployment()//创建⼀个部署对象.name("流程定义⼊门")//添加部署名称.addClasspathResource("diagrams/helloworld.bpmn")//从calsspath中加载,⼀次⼀个.addClasspathResource("diagrams/helloworld.png").deploy();//完成部署System.out.println(deployment.getId());System.out.println(deployment.getName());} 通过zip压缩包代码如下public void deploymentProcessDefinition_zip(){InputStream in = this.getClass().getClassLoader().getResourceAsStream("diagrams/helloworld.zip");//从zip获得输⼊流ZipInputStream zipInputStream = new ZipInputStream(in);Deployment deployment = processEngine.getRepositoryService()//与流程定义和部署相关的service.createDeployment()//创建⼀个部署对象.name("流程定义zip")//添加部署名称.addZipInputStream(zipInputStream)//指定zip格式⽂件完成部署.deploy();//完成部署System.out.println(deployment.getId());System.out.println(deployment.getName());} 查询流程定义代码如下public void findProcessDefinition(){List<ProcessDefinition> list = processEngine.getRepositoryService()//与流程定义和部署相关的service.createProcessDefinitionQuery()//查询流程定义表/**指定条件查询**///.deploymentId(deploymentId)//部署对象id查询//.processDefinitionId(processDefinitionId)//流程定义id查询//.processDefinitionKey(processDefinitionKey)//流程定义的key查询集合//.processDefinitionKeyLike(processDefinitionKeyLike)//流程定义的key模糊查询集合/**排序**///.orderByProcessDefinitionVersion().asc()//按版本升序//.orderByProcessDefinitionVersion().asc()//按版本升降序.list();//返回⼀个集合列表,封装流程定义//.singleResult();//返回惟⼀结果集//.count();//返回结果集数量//.listPage(firstResult, maxResults);//分页查询if(list!=null && list.size()>0){for(ProcessDefinition pd:list){System.out.println("流程定义ID:"+pd.getId());//流程定义的key+版本+随机⽣成数System.out.println("流程定义的名称:"+pd.getName());//对应helloworld.bpmn⽂件中的name属性值System.out.println("流程定义的key:"+pd.getKey());//对应helloworld.bpmn⽂件中的id属性值System.out.println("流程定义的版本:"+pd.getVersion());//当流程定义的key值相同的相同下,版本升级,默认1System.out.println("资源名称bpmn⽂件:"+pd.getResourceName());System.out.println("资源名称png⽂件:"+pd.getDiagramResourceName());System.out.println("部署对象ID:"+pd.getDeploymentId());System.out.println("#########################################################");}}} 删除流程定义代码如下,分为级联和⾮级联删除两种public void deleteProcessDefinition(){String deploymentId="601";//使⽤部署id完成删除/*** 不带级联的删除* 只能删除没有启动的流程,如果流程启动,就会抛出异常*///processEngine.getRepositoryService()// .deleteDeployment(deploymentId);//System.out.println("success");processEngine.getRepositoryService()//.deleteDeployment(deploymentId, true);System.out.println("删除成功!");} 查看流程图图⽚代码如下public void viewPic() throws IOException{/**将⽣成图⽚放到⽂件夹下*/String deploymentId = "1";//获取图⽚资源名称List<String> list = processEngine.getRepositoryService()//.getDeploymentResourceNames(deploymentId);//定义图⽚资源的名称String resourceName = "";if(list!=null && list.size()>0){for(String name:list){if(name.indexOf(".png")>=0){resourceName = name;}}}//获取图⽚的输⼊流InputStream in = processEngine.getRepositoryService()//.getResourceAsStream(deploymentId, resourceName);System.out.println(resourceName);//将图⽚⽣成到D盘的⽬录下File file = new File("D:/"+resourceName);//将输⼊流的图⽚写到D盘下FileUtils.copyInputStreamToFile(in, file);} 整体⽂件代码如下package b_processDefinition;import java.io.File;import java.io.IOException;import java.io.InputStream;import java.util.ArrayList;import java.util.LinkedHashMap;import java.util.List;import java.util.Map;import java.util.zip.ZipInputStream;import org.activiti.engine.ProcessEngine;import org.activiti.engine.ProcessEngines;import org.activiti.engine.repository.Deployment;import org.activiti.engine.repository.ProcessDefinition;import mons.io.FileUtils;import org.junit.Test;public class ProcessDefinitionTest {ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();/**部署流程定义,从classpath*/@Testpublic void deploymentProcessDefinition_classpath(){Deployment deployment = processEngine.getRepositoryService()//与流程定义和部署相关的service .createDeployment()//创建⼀个部署对象.name("流程定义⼊门")//添加部署名称.addClasspathResource("diagrams/helloworld.bpmn")//从calsspath中加载,⼀次⼀个.addClasspathResource("diagrams/helloworld.png").deploy();//完成部署System.out.println(deployment.getId());System.out.println(deployment.getName());}/**部署流程定义,从zip*/@Testpublic void deploymentProcessDefinition_zip(){InputStream in = this.getClass().getClassLoader().getResourceAsStream("diagrams/helloworld.zip");//从zip获得输⼊流 ZipInputStream zipInputStream = new ZipInputStream(in);Deployment deployment = processEngine.getRepositoryService()//与流程定义和部署相关的service.createDeployment()//创建⼀个部署对象.name("流程定义zip")//添加部署名称.addZipInputStream(zipInputStream)//指定zip格式⽂件完成部署.deploy();//完成部署System.out.println(deployment.getId());System.out.println(deployment.getName());}/**查询流程定义*/@Testpublic void findProcessDefinition(){List<ProcessDefinition> list = processEngine.getRepositoryService()//与流程定义和部署相关的service.createProcessDefinitionQuery()//查询流程定义表/**指定条件查询**///.deploymentId(deploymentId)//部署对象id查询//.processDefinitionId(processDefinitionId)//流程定义id查询//.processDefinitionKey(processDefinitionKey)//流程定义的key查询集合//.processDefinitionKeyLike(processDefinitionKeyLike)//流程定义的key模糊查询集合/**排序**///.orderByProcessDefinitionVersion().asc()//按版本升序//.orderByProcessDefinitionVersion().asc()//按版本升降序.list();//返回⼀个集合列表,封装流程定义//.singleResult();//返回惟⼀结果集//.count();//返回结果集数量//.listPage(firstResult, maxResults);//分页查询if(list!=null && list.size()>0){for(ProcessDefinition pd:list){System.out.println("流程定义ID:"+pd.getId());//流程定义的key+版本+随机⽣成数System.out.println("流程定义的名称:"+pd.getName());//对应helloworld.bpmn⽂件中的name属性值System.out.println("流程定义的key:"+pd.getKey());//对应helloworld.bpmn⽂件中的id属性值System.out.println("流程定义的版本:"+pd.getVersion());//当流程定义的key值相同的相同下,版本升级,默认1System.out.println("资源名称bpmn⽂件:"+pd.getResourceName());System.out.println("资源名称png⽂件:"+pd.getDiagramResourceName());System.out.println("部署对象ID:"+pd.getDeploymentId());System.out.println("#########################################################");}}}/**删除流程定义**/@Testpublic void deleteProcessDefinition(){String deploymentId="601";//使⽤部署id完成删除/*** 不带级联的删除* 只能删除没有启动的流程,如果流程启动,就会抛出异常*///processEngine.getRepositoryService()// .deleteDeployment(deploymentId);//System.out.println("success");processEngine.getRepositoryService()//.deleteDeployment(deploymentId, true);System.out.println("删除成功!");}/**查看流程图* @throws IOException */@Testpublic void viewPic() throws IOException{/**将⽣成图⽚放到⽂件夹下*/String deploymentId = "1";//获取图⽚资源名称List<String> list = processEngine.getRepositoryService()//.getDeploymentResourceNames(deploymentId);//定义图⽚资源的名称String resourceName = "";if(list!=null && list.size()>0){for(String name:list){if(name.indexOf(".png")>=0){resourceName = name;}}}//获取图⽚的输⼊流InputStream in = processEngine.getRepositoryService()//.getResourceAsStream(deploymentId, resourceName);System.out.println(resourceName);//将图⽚⽣成到D盘的⽬录下File file = new File("D:/"+resourceName);//将输⼊流的图⽚写到D盘下FileUtils.copyInputStreamToFile(in, file);}/***附加功能:查询最新版本的流程定义*/@Testpublic void findLastVersionProcessDefinition(){List<ProcessDefinition> list = processEngine.getRepositoryService()//.createProcessDefinitionQuery()//.orderByProcessDefinitionVersion().asc()//使⽤流程定义的版本升序排列.list();/*** Map<String,ProcessDefinition>map集合的key:流程定义的keymap集合的value:流程定义的对象map集合的特点:当map集合key值相同的情况下,后⼀次的值将替换前⼀次的值*/Map<String, ProcessDefinition> map = new LinkedHashMap<String, ProcessDefinition>();if(list!=null && list.size()>0){for(ProcessDefinition pd:list){map.put(pd.getKey(), pd);}}List<ProcessDefinition> pdList = new ArrayList<ProcessDefinition>(map.values());if(pdList!=null && pdList.size()>0){for(ProcessDefinition pd:pdList){System.out.println("流程定义ID:"+pd.getId());//流程定义的key+版本+随机⽣成数System.out.println("流程定义的名称:"+pd.getName());//对应helloworld.bpmn⽂件中的name属性值System.out.println("流程定义的key:"+pd.getKey());//对应helloworld.bpmn⽂件中的id属性值System.out.println("流程定义的版本:"+pd.getVersion());//当流程定义的key值相同的相同下,版本升级,默认1 System.out.println("资源名称bpmn⽂件:"+pd.getResourceName());System.out.println("资源名称png⽂件:"+pd.getDiagramResourceName());System.out.println("部署对象ID:"+pd.getDeploymentId());System.out.println("#########################################################");}}}/**附加功能:删除流程定义(删除key相同的所有不同版本的流程定义)*/@Testpublic void deleteProcessDefinitionByKey(){//流程定义的keyString processDefinitionKey = "helloworld";//先使⽤流程定义的key查询流程定义,查询出所有的版本List<ProcessDefinition> list = processEngine.getRepositoryService()//.createProcessDefinitionQuery()//.processDefinitionKey(processDefinitionKey)//使⽤流程定义的key查询.list();//遍历,获取每个流程定义的部署IDif(list!=null && list.size()>0){for(ProcessDefinition pd:list){//获取部署IDString deploymentId = pd.getDeploymentId();processEngine.getRepositoryService()//.deleteDeployment(deploymentId, true);}}}}。

Activiti工作流入门详解完整教学教程

Activiti工作流入门详解完整教学教程

Activiti入门教程详解完整教程1.A ctiviti介绍Activiti是由Alfresco软件在2010年5月17日发布的业务流程管理(BPM)框架,它是覆盖了业务流程管理,工作流,服务协作等领域的一个开源,灵活的,易扩展的可执行流程语言框架。

Activiti基于Apache许可的开源BPM平台,创始人Tom Baeyens是JBoss JBPM的项目架构师,它的特色是提供了eclipse插件,开发人员可以通过插件直接绘画出业务流程图。

1.1工作流引擎ProcessEngine对象,这是Activiti工作的核心。

负责生成流程运行时的各种实例及数据,监控和管理流程的运行。

1.2BPMN业务流程建模与标注(Business Process Model and Notation,BPMN),描述流程的基本符号,包括这些图元如何组合成一个业务流程图(Business Process Diagram)2.准备环境2.1Activiti软件环境1)JDK1.6或者更高版本2)支持的数据库有:h2,mysql,oracle,mysql,db2等3)支持Activiti运行的jar包,可以通过maven依赖引入4)开发环境为Eclipse3.7或者以上版本,myeclipse为8.6版本2.2安装流程设计器(eclipse插件)1)打开Help →Install New Software →Add输入Name: Activiti DesignerLocation: /designer/update/输入完成后,单击OK按钮等待下载完成后安装。

安装完成后在菜单选项中会出现Activiti的目录选项2.3 设置eclipse activit插件的画流程图选项打开菜单Windows --> Preferences --> Activiti -->Save 下流程图片的生成方式勾选上Create process definition image when saving the diagram操作,勾选上这个操作后在画流程图后保存eclipse会自动生成对应的流程图片。

Activiti6.0工作流使用说明文档V1.0

Activiti6.0工作流使用说明文档V1.0

Activiti工作流使用说明文档V1.02019年8月9日目录一、模型设计器 (4)1.1任务 (5)1.1.1 用户任务 (5)1.1.2 服务任务 (5)1.1.3 脚本任务 (6)1.1.4 业务规则任务 (7)1.1.5 接收任务 (7)1.1.6 手动任务 (7)1.1.7 邮件任务 (8)1.1.8 Camel任务 (8)1.1.9 Mule任务 (8)1.1.10 决策任务 (9)1.2构造 (10)1.2.1 子流程 (10)1.2.2 事件子流程 (11)1.3泳道列表 (11)1.4分支 (12)1.4.1 排他分支 (12)1.4.2 并行分支 (12)1.4.3 包容分支 (13)1.4.4 事件分支 (13)1.5事件 (14)1.5.1 定时器事件 (14)1.5.2 信号事件 (14)1.5.3 消息事件 (16)1.5.4 错误事件 (16)1.5.5 边界事件 (17)1.5.6 中间事件 (18)1.5.7 开始事件 (18)1.5.8 结束事件 (18)1.6属性元素 (18)1.6.1 异步 (18)1.6.2 排他 (19)1.6.3 补偿 (19)1.6.4 中断任务 (20)1.6.5 分配 (21)1.6.6 到期时间 (22)1.6.7 表单 (22)1.6.8 表达式 (24)1.6.9 多实例 (25)1.7监听器配置 (28)1.7.1 执行监听器 (29)1.7.2 任务监听器 (30)1.7.3 事件监听器 (32)1.7.4 全局事件监听器 (33)二、workflow-service (34)2.1数据更新逻辑 (34)2.2方法表达式配置 (35)2.3自定义外置表单 (36)2.4事件监听器配置 (37)2.5方法调用说明 (37)三、常见问题 (37)一、模型设计器模型设计器项目qqdznyyglpt-workflow-designer主要完成自定义流程、表单设计,可以在模型设计器中完成整个功能的流转,但仅限与admin(密码默认为test)相同租户的用户可使用全功能,其他租户用户登录后只有流程设计、表单配置、决策表配置功能,无法在设计器进行流程执行。

Activiti6.0工作流使用说明文档V1.0

Activiti6.0工作流使用说明文档V1.0

Activiti工作流使用说明文档V1.02019年8月9日目录一、模型设计器 (4)1.1任务 (5)1.1.1 用户任务 (5)1.1.2 服务任务 (5)1.1.3 脚本任务 (6)1.1.4 业务规则任务 (7)1.1.5 接收任务 (7)1.1.6 手动任务 (7)1.1.7 邮件任务 (8)1.1.8 Camel任务 (8)1.1.9 Mule任务 (8)1.1.10 决策任务 (9)1.2构造 (10)1.2.1 子流程 (10)1.2.2 事件子流程 (11)1.3泳道列表 (11)1.4分支 (12)1.4.1 排他分支 (12)1.4.2 并行分支 (12)1.4.3 包容分支 (13)1.4.4 事件分支 (13)1.5事件 (14)1.5.1 定时器事件 (14)1.5.2 信号事件 (14)1.5.3 消息事件 (16)1.5.4 错误事件 (16)1.5.5 边界事件 (17)1.5.6 中间事件 (18)1.5.7 开始事件 (18)1.5.8 结束事件 (18)1.6属性元素 (18)1.6.1 异步 (18)1.6.2 排他 (19)1.6.3 补偿 (19)1.6.4 中断任务 (20)1.6.5 分配 (21)1.6.6 到期时间 (22)1.6.7 表单 (22)1.6.8 表达式 (24)1.6.9 多实例 (25)1.7监听器配置 (28)1.7.1 执行监听器 (29)1.7.2 任务监听器 (30)1.7.3 事件监听器 (32)1.7.4 全局事件监听器 (33)二、workflow-service (34)2.1数据更新逻辑 (34)2.2方法表达式配置 (35)2.3自定义外置表单 (36)2.4事件监听器配置 (37)2.5方法调用说明 (37)三、常见问题 (37)一、模型设计器模型设计器项目qqdznyyglpt-workflow-designer主要完成自定义流程、表单设计,可以在模型设计器中完成整个功能的流转,但仅限与admin(密码默认为test)相同租户的用户可使用全功能,其他租户用户登录后只有流程设计、表单配置、决策表配置功能,无法在设计器进行流程执行。

activiti流程文件细解

activiti流程文件细解

Activiti流程文件细解-》Pracess(该流程的基本数据,流程名字等) -----3 -》Data Objects--------------------------4-》Listeners(执行监听器)----------------5 -》--》Java class----------------------6-》--》Expression----------------------6 -》--》Delegate Expression-------------7 -》启动节点-----------------------------------------8-》--》General------------------------------8 -》--》Main config--------------------------9-》--》Documentation------------------------9-》--》Form--------------------------------101、动态表单----------------------------------------------------------102、外置表单----------------------------------------------------------113、普通表单----------------------------------------------------------12-》Listeners-----------------------------13 -》任务-------------------------------------------14-》!--》User Task-------------------------14-》--》General----------------------14-》--》Main config------------------15-》-》Listeners-------------------16 -》-》Multi instance--------------16 -》网关--------------------------------------------17流程文件:-》Pracess(该流程的基本数据,流程名字等)-----------------------------------------------------<process id="Process"name="请假流程-普通表单" isExecutable="true"><documentation>请假流程演示</documentation></process>------------------------------------------------------》Data Objects(插入一条可以公用的数据)-----------------------------------------------------<process id="myProcess"name="My process"isExecutable="true"> <documentation>这是一个演示</documentation><dataObject id="wsy"name="wsy"itemSubjectRef="xsd:string"><extensionElements><activiti:value>汪诗雨</activiti:value></extensionElements></dataObject></process>------------------------------------------------------》Listeners(执行监听器)Java class ,Expression,Delegate expression 都有域,其中的值可以传给监听器-----------------------------------------------------<extensionElements><activiti:executionListener event="start"class="org.xdemo.example.activiti.Cdi.event.ABC"><activiti:field name="user"><activiti:string><![CDATA[HelloWord]]></activiti:string></activiti:field></activiti:executionListener></extensionElements>------------------------------------------------------》--》Java class注意:class需要实现接口org.activiti.engine.delegate.ExecutionListener-----------------------------------------------------<process id="myProcess"name="My process"isExecutable="true"> <documentation>这是一个演示</documentation><extensionElements><activiti:executionListener event="start"class="org.xdemo.example.activiti.Cdi.event.ABC"></activiti:executionListener></extensionElements></process>------------------------------------------------------》--》Expression定义一个表达式类似EL语法。

Activiti之流程通过、驳回、会签、转办、中止、挂起等核心操作封装(Activiti5.9)

Activiti之流程通过、驳回、会签、转办、中止、挂起等核心操作封装(Activiti5.9)

Activiti之流程通过、驳回、会签、转办、中⽌、挂起等核⼼操作封装(Activiti5.9)/rosten/article/details/383002671package com.famousPro.process.service.impl;23import java.util.ArrayList;4import java.util.HashMap;5import java.util.List;6import java.util.Map;78import org.activiti.engine.FormService;9import org.activiti.engine.HistoryService;10import org.activiti.engine.RepositoryService;11import org.activiti.engine.RuntimeService;12import org.activiti.engine.TaskService;13import org.activiti.engine.history.HistoricActivityInstance;14import org.activiti.engine.impl.RepositoryServiceImpl;15import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;16import org.activiti.engine.impl.persistence.entity.TaskEntity;17import org.activiti.engine.impl.pvm.PvmTransition;18import org.activiti.engine.impl.pvm.process.ActivityImpl;19import org.activiti.engine.impl.pvm.process.ProcessDefinitionImpl;20import org.activiti.engine.impl.pvm.process.TransitionImpl;21import org.activiti.engine.runtime.ProcessInstance;22import org.activiti.engine.task.Task;2324import mon.service.impl.BaseServiceImp;25import mon.util.IDGenerator;26import mon.util.StringUtil;27import com.famousPro.process.service.ProcessCoreService;28import com.famousPro.process.service.ProcessOtherService;2930/**31 * 流程操作核⼼类<br>32 * 此核⼼类主要处理:流程通过、驳回、会签、转办、中⽌、挂起等核⼼操作<br>33 *34 * @author wangfuwei35 *36*/37public class ProcessCoreServiceImpl extends BaseServiceImp implements38 ProcessCoreService {39protected RepositoryService repositoryService;4041protected RuntimeService runtimeService;4243protected TaskService taskService;4445protected FormService formService;4647protected HistoryService historyService;4849protected ProcessOtherService processOtherService;5051/**52 * 根据当前任务ID,查询可以驳回的任务节点53 *54 * @param taskId55 * 当前任务ID56*/57public List<ActivityImpl> findBackAvtivity(String taskId) throws Exception {58 List<ActivityImpl> rtnList = null;59if (processOtherService.isJointTask(taskId)) {// 会签任务节点,不允许驳回60 rtnList = new ArrayList<ActivityImpl>();61 } else {62 rtnList = iteratorBackActivity(taskId, findActivitiImpl(taskId,63null), new ArrayList<ActivityImpl>(),64new ArrayList<ActivityImpl>());65 }66return reverList(rtnList);67 }6869/**70 * 审批通过(驳回直接跳回功能需后续扩展)71 *72 * @param taskId73 * 当前任务ID74 * @param variables75 * 流程存储参数78public void passProcess(String taskId, Map<String, Object> variables)79throws Exception {80 List<Task> tasks = taskService.createTaskQuery().parentTaskId(taskId)81 .taskDescription("jointProcess").list();82for (Task task : tasks) {// 级联结束本节点发起的会签任务83 commitProcess(task.getId(), null, null);84 }85 commitProcess(taskId, variables, null);86 }8788/**89 * 驳回流程90 *91 * @param taskId92 * 当前任务ID93 * @param activityId94 * 驳回节点ID95 * @param variables96 * 流程存储参数97 * @throws Exception98*/99public void backProcess(String taskId, String activityId,100 Map<String, Object> variables) throws Exception {101if (StringUtil.isNull(activityId)) {102throw new Exception("驳回⽬标节点ID为空!");103 }104105// 查询本节点发起的会签任务,并结束106 List<Task> tasks = taskService.createTaskQuery().parentTaskId(taskId) 107 .taskDescription("jointProcess").list();108for (Task task : tasks) {109 commitProcess(task.getId(), null, null);110 }111112// 查找所有并⾏任务节点,同时驳回113 List<Task> taskList = findTaskListByKey(findProcessInstanceByTaskId( 114 taskId).getId(), findTaskById(taskId).getTaskDefinitionKey());115for (Task task : taskList) {116 commitProcess(task.getId(), variables, activityId);117 }118 }119120/**121 * 取回流程122 *123 * @param taskId124 * 当前任务ID125 * @param activityId126 * 取回节点ID127 * @throws Exception128*/129public void callBackProcess(String taskId, String activityId)130throws Exception {131if (StringUtil.isNull(activityId)) {132throw new Exception("⽬标节点ID为空!");133 }134135// 查找所有并⾏任务节点,同时取回136 List<Task> taskList = findTaskListByKey(findProcessInstanceByTaskId( 137 taskId).getId(), findTaskById(taskId).getTaskDefinitionKey());138for (Task task : taskList) {139 commitProcess(task.getId(), null, activityId);140 }141 }142143/**144 * 中⽌流程(特权⼈直接审批通过等)145 *146 * @param taskId147*/148public void endProcess(String taskId) throws Exception {149 ActivityImpl endActivity = findActivitiImpl(taskId, "end");150 commitProcess(taskId, null, endActivity.getId());151 }152153/**154 * 会签操作155 *156 * @param taskId157 * 当前任务ID158 * @param userCodes159 * 会签⼈账号集合162public void jointProcess(String taskId, List<String> userCodes)163throws Exception {164for (String userCode : userCodes) {165 TaskEntity task = (TaskEntity) taskService.newTask(IDGenerator166 .generateID());167 task.setAssignee(userCode);168 task.setName(findTaskById(taskId).getName() + "-会签");169 task.setProcessDefinitionId(findProcessDefinitionEntityByTaskId(170 taskId).getId());171 task.setProcessInstanceId(findProcessInstanceByTaskId(taskId)172 .getId());173 task.setParentTaskId(taskId);174 task.setDescription("jointProcess");175 taskService.saveTask(task);176 }177 }178179/**180 * 转办流程181 *182 * @param taskId183 * 当前任务节点ID184 * @param userCode185 * 被转办⼈Code186*/187public void transferAssignee(String taskId, String userCode) {188 taskService.setAssignee(taskId, userCode);189 }190191/**192 * ***************************************************************************************************************************************************<br>193 * ************************************************以下为流程会签操作核⼼逻辑******************************************************************************<br> 194 * ***************************************************************************************************************************************************<br>195*/196197/**198 * ***************************************************************************************************************************************************<br>199 * ************************************************以上为流程会签操作核⼼逻辑******************************************************************************<br> 200 * ***************************************************************************************************************************************************<br>201*/202203/**204 * ***************************************************************************************************************************************************<br>205 * ************************************************以下为流程转向操作核⼼逻辑******************************************************************************<br> 206 * ***************************************************************************************************************************************************<br>207*/208209/**210 * @param taskId211 * 当前任务ID212 * @param variables213 * 流程变量214 * @param activityId215 * 流程转向执⾏任务节点ID<br>216 * 此参数为空,默认为提交操作217 * @throws Exception218*/219private void commitProcess(String taskId, Map<String, Object> variables,220 String activityId) throws Exception {221if (variables == null) {222 variables = new HashMap<String, Object>();223 }224// 跳转节点为空,默认提交操作225if (StringUtil.isNull(activityId)) {226 plete(taskId, variables);227 } else {// 流程转向操作228 turnTransition(taskId, activityId, variables);229 }230 }231232/**233 * 清空指定活动节点流向234 *235 * @param activityImpl236 * 活动节点237 * @return节点流向集合238*/239private List<PvmTransition> clearTransition(ActivityImpl activityImpl) {240// 存储当前节点所有流向临时变量241 List<PvmTransition> oriPvmTransitionList = new ArrayList<PvmTransition>();242// 获取当前节点所有流向,存储到临时变量,然后清空243 List<PvmTransition> pvmTransitionList = activityImpl244 .getOutgoingTransitions();245for (PvmTransition pvmTransition : pvmTransitionList) {246 oriPvmTransitionList.add(pvmTransition);247 }248 pvmTransitionList.clear();249250return oriPvmTransitionList;251 }252253/**254 * 还原指定活动节点流向255 *256 * @param activityImpl257 * 活动节点258 * @param oriPvmTransitionList259 * 原有节点流向集合260*/261private void restoreTransition(ActivityImpl activityImpl,262 List<PvmTransition> oriPvmTransitionList) {263// 清空现有流向264 List<PvmTransition> pvmTransitionList = activityImpl265 .getOutgoingTransitions();266 pvmTransitionList.clear();267// 还原以前流向268for (PvmTransition pvmTransition : oriPvmTransitionList) {269 pvmTransitionList.add(pvmTransition);270 }271 }272273/**274 * 流程转向操作275 *276 * @param taskId277 * 当前任务ID278 * @param activityId279 * ⽬标节点任务ID280 * @param variables281 * 流程变量282 * @throws Exception283*/284private void turnTransition(String taskId, String activityId,285 Map<String, Object> variables) throws Exception {286// 当前节点287 ActivityImpl currActivity = findActivitiImpl(taskId, null);288// 清空当前流向289 List<PvmTransition> oriPvmTransitionList = clearTransition(currActivity);290291// 创建新流向292 TransitionImpl newTransition = currActivity.createOutgoingTransition();293// ⽬标节点294 ActivityImpl pointActivity = findActivitiImpl(taskId, activityId);295// 设置新流向的⽬标节点296 newTransition.setDestination(pointActivity);297298// 执⾏转向任务299 plete(taskId, variables);300// 删除⽬标节点新流⼊301 pointActivity.getIncomingTransitions().remove(newTransition);302303// 还原以前流向304 restoreTransition(currActivity, oriPvmTransitionList);305 }306307/**308 * ***************************************************************************************************************************************************<br>309 * ************************************************以上为流程转向操作核⼼逻辑******************************************************************************<br> 310 * ***************************************************************************************************************************************************<br>311*/312313/**314 * ***************************************************************************************************************************************************<br>315 * ************************************************以下为查询流程驳回节点核⼼逻辑***************************************************************************<br> 316 * ***************************************************************************************************************************************************<br>317*/318319/**320 * 迭代循环流程树结构,查询当前节点可驳回的任务节点321 *322 * @param taskId323 * 当前任务ID324 * @param currActivity325 * 当前活动节点326 * @param rtnList327 * 存储回退节点集合328 * @param tempList329 * 临时存储节点集合(存储⼀次迭代过程中的同级userTask节点)330 * @return回退节点集合331*/332private List<ActivityImpl> iteratorBackActivity(String taskId,333 ActivityImpl currActivity, List<ActivityImpl> rtnList,334 List<ActivityImpl> tempList) throws Exception {335// 查询流程定义,⽣成流程树结构336 ProcessInstance processInstance = findProcessInstanceByTaskId(taskId);337338// 当前节点的流⼊来源339 List<PvmTransition> incomingTransitions = currActivity340 .getIncomingTransitions();341// 条件分⽀节点集合,userTask节点遍历完毕,迭代遍历此集合,查询条件分⽀对应的userTask节点342 List<ActivityImpl> exclusiveGateways = new ArrayList<ActivityImpl>();343// 并⾏节点集合,userTask节点遍历完毕,迭代遍历此集合,查询并⾏节点对应的userTask节点344 List<ActivityImpl> parallelGateways = new ArrayList<ActivityImpl>();345// 遍历当前节点所有流⼊路径346for (PvmTransition pvmTransition : incomingTransitions) {347 TransitionImpl transitionImpl = (TransitionImpl) pvmTransition;348 ActivityImpl activityImpl = transitionImpl.getSource();349 String type = (String) activityImpl.getProperty("type");350/**351 * 并⾏节点配置要求:<br>352 * 必须成对出现,且要求分别配置节点ID为:XXX_start(开始),XXX_end(结束)353*/354if ("parallelGateway".equals(type)) {// 并⾏路线355 String gatewayId = activityImpl.getId();356 String gatewayType = gatewayId.substring(gatewayId357 .lastIndexOf("_") + 1);358if ("START".equals(gatewayType.toUpperCase())) {// 并⾏起点,停⽌递归359return rtnList;360 } else {// 并⾏终点,临时存储此节点,本次循环结束,迭代集合,查询对应的userTask节点361 parallelGateways.add(activityImpl);362 }363 } else if ("startEvent".equals(type)) {// 开始节点,停⽌递归364return rtnList;365 } else if ("userTask".equals(type)) {// ⽤户任务366 tempList.add(activityImpl);367 } else if ("exclusiveGateway".equals(type)) {// 分⽀路线,临时存储此节点,本次循环结束,迭代集合,查询对应的userTask节点368 currActivity = transitionImpl.getSource();369 exclusiveGateways.add(currActivity);370 }371 }372373/**374 * 迭代条件分⽀集合,查询对应的userTask节点375*/376for (ActivityImpl activityImpl : exclusiveGateways) {377 iteratorBackActivity(taskId, activityImpl, rtnList, tempList);378 }379380/**381 * 迭代并⾏集合,查询对应的userTask节点382*/383for (ActivityImpl activityImpl : parallelGateways) {384 iteratorBackActivity(taskId, activityImpl, rtnList, tempList);385 }386387/**388 * 根据同级userTask集合,过滤最近发⽣的节点389*/390 currActivity = filterNewestActivity(processInstance, tempList);391if (currActivity != null) {392// 查询当前节点的流向是否为并⾏终点,并获取并⾏起点ID393 String id = findParallelGatewayId(currActivity);394if (StringUtil.isNull(id)) {// 并⾏起点ID为空,此节点流向不是并⾏终点,符合驳回条件,存储此节点395 rtnList.add(currActivity);396 } else {// 根据并⾏起点ID查询当前节点,然后迭代查询其对应的userTask任务节点397 currActivity = findActivitiImpl(taskId, id);398 }399400// 清空本次迭代临时集合401 tempList.clear();402// 执⾏下次迭代403 iteratorBackActivity(taskId, currActivity, rtnList, tempList);404 }405return rtnList;406 }407408/**409 * 反向排序list集合,便于驳回节点按顺序显⽰410 *411 * @param list412 * @return413*/414private List<ActivityImpl> reverList(List<ActivityImpl> list) {415 List<ActivityImpl> rtnList = new ArrayList<ActivityImpl>();416// 由于迭代出现重复数据,排除重复417for (int i = list.size(); i > 0; i--) {418if (!rtnList.contains(list.get(i - 1)))419 rtnList.add(list.get(i - 1));420 }421return rtnList;422 }423424/**425 * 根据当前节点,查询输出流向是否为并⾏终点,如果为并⾏终点,则拼装对应的并⾏起点ID 426 *427 * @param activityImpl428 * 当前节点429 * @return430*/431private String findParallelGatewayId(ActivityImpl activityImpl) {432 List<PvmTransition> incomingTransitions = activityImpl433 .getOutgoingTransitions();434for (PvmTransition pvmTransition : incomingTransitions) {435 TransitionImpl transitionImpl = (TransitionImpl) pvmTransition;436 activityImpl = transitionImpl.getDestination();437 String type = (String) activityImpl.getProperty("type");438if ("parallelGateway".equals(type)) {// 并⾏路线439 String gatewayId = activityImpl.getId();440 String gatewayType = gatewayId.substring(gatewayId441 .lastIndexOf("_") + 1);442if ("END".equals(gatewayType.toUpperCase())) {443return gatewayId.substring(0, stIndexOf("_"))444 + "_start";445 }446 }447 }448return null;449 }450451/**452 * 根据流⼊任务集合,查询最近⼀次的流⼊任务节点453 *454 * @param processInstance455 * 流程实例456 * @param tempList457 * 流⼊任务集合458 * @return459*/460private ActivityImpl filterNewestActivity(ProcessInstance processInstance,461 List<ActivityImpl> tempList) {462while (tempList.size() > 0) {463 ActivityImpl activity_1 = tempList.get(0);464 HistoricActivityInstance activityInstance_1 = findHistoricUserTask(465 processInstance, activity_1.getId());466if (activityInstance_1 == null) {467 tempList.remove(activity_1);468continue;469 }470471if (tempList.size() > 1) {472 ActivityImpl activity_2 = tempList.get(1);473 HistoricActivityInstance activityInstance_2 = findHistoricUserTask(474 processInstance, activity_2.getId());475if (activityInstance_2 == null) {476 tempList.remove(activity_2);477continue;478 }479480if (activityInstance_1.getEndTime().before(481 activityInstance_2.getEndTime())) {482 tempList.remove(activity_1);483 } else {484 tempList.remove(activity_2);485 }486 } else {487break;488 }489 }490if (tempList.size() > 0) {491return tempList.get(0);492 }493return null;494 }495496/**497 * 查询指定任务节点的最新记录498 *499 * @param processInstance500 * 流程实例501 * @param activityId502 * @return503*/504private HistoricActivityInstance findHistoricUserTask(505 ProcessInstance processInstance, String activityId) {506 HistoricActivityInstance rtnVal = null;507// 查询当前流程实例审批结束的历史节点508 List<HistoricActivityInstance> historicActivityInstances = historyService509 .createHistoricActivityInstanceQuery().activityType("userTask")510 .processInstanceId(processInstance.getId()).activityId(511 activityId).finished()512 .orderByHistoricActivityInstanceEndTime().desc().list();513if (historicActivityInstances.size() > 0) {514 rtnVal = historicActivityInstances.get(0);515 }516517return rtnVal;518 }519520/**521 * *******************************************************************************************************<br>522 * ********************************以上为查询流程驳回节点核⼼逻辑***********************************************<br> 523 * ********************************************************************************************************<br>524*/525526/**527 * ********************************************************************************<br>528 * **********************以下为activiti 核⼼service529 * set⽅法***************************<br>530 * *********************************************************************************<br>531*/532public void setFormService(FormService formService) {533this.formService = formService;534 }535536public void setHistoryService(HistoryService historyService) {537this.historyService = historyService;538 }539540public void setRepositoryService(RepositoryService repositoryService) {541this.repositoryService = repositoryService;542 }543544public void setRuntimeService(RuntimeService runtimeService) {545this.runtimeService = runtimeService;546 }547548public void setTaskService(TaskService taskService) {549this.taskService = taskService;550 }551552/**553 * ********************************************************************************<br>554 * **********************以上为activiti 核⼼service555 * set⽅法***************************<br>556 * *********************************************************************************<br>557*/558559/**560 * ********************************************************************************<br>561 * **********************以下为根据任务节点ID 获取流程各对象查询⽅法**********************<br>562 * *********************************************************************************<br>563*/564565public void setProcessOtherService(ProcessOtherService processOtherService) {566this.processOtherService = processOtherService;567 }568569/**570 * 根据任务ID获得任务实例571 *572 * @param taskId573 * 任务ID574 * @return575 * @throws Exception576*/577private TaskEntity findTaskById(String taskId) throws Exception {578 TaskEntity task = (TaskEntity) taskService.createTaskQuery().taskId(579 taskId).singleResult();580if (task == null) {581throw new Exception("任务实例未找到!");582 }583return task;584 }585586/**587 * 根据流程实例ID和任务key值查询所有同级任务集合588 *589 * @param processInstanceId590 * @param key591 * @return592*/593private List<Task> findTaskListByKey(String processInstanceId, String key) {594return taskService.createTaskQuery().processInstanceId(595 processInstanceId).taskDefinitionKey(key).list();596 }597598/**599 * 根据任务ID获取对应的流程实例600 *601 * @param taskId602 * 任务ID603 * @return604 * @throws Exception605*/606private ProcessInstance findProcessInstanceByTaskId(String taskId)607throws Exception {608// 找到流程实例609 ProcessInstance processInstance = runtimeService610 .createProcessInstanceQuery().processInstanceId(611 findTaskById(taskId).getProcessInstanceId())612 .singleResult();613if (processInstance == null) {614throw new Exception("流程实例未找到!");615 }616return processInstance;617 }618619/**620 * 根据任务ID获取流程定义621 *622 * @param taskId623 * 任务ID624 * @return625 * @throws Exception626*/627private ProcessDefinitionEntity findProcessDefinitionEntityByTaskId(628 String taskId) throws Exception {629// 取得流程定义630 ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) ((RepositoryServiceImpl) repositoryService) 631 .getDeployedProcessDefinition(findTaskById(taskId)632 .getProcessDefinitionId());633634if (processDefinition == null) {635throw new Exception("流程定义未找到!");636 }637638return processDefinition;639 }640641/**642 * 根据任务ID和节点ID获取活动节点 <br>643 *644 * @param taskId645 * 任务ID646 * @param activityId647 * 活动节点ID <br>648 * 如果为null或"",则默认查询当前活动节点 <br>649 * 如果为"end",则查询结束节点 <br>650 *651 * @return652 * @throws Exception653*/654private ActivityImpl findActivitiImpl(String taskId, String activityId)655throws Exception {656// 取得流程定义657 ProcessDefinitionEntity processDefinition = findProcessDefinitionEntityByTaskId(taskId);658659// 获取当前活动节点ID660if (StringUtil.isNull(activityId)) {661 activityId = findTaskById(taskId).getTaskDefinitionKey();662 }663664// 根据流程定义,获取该流程实例的结束节点665if (activityId.toUpperCase().equals("END")) {666for (ActivityImpl activityImpl : processDefinition.getActivities()) {667 List<PvmTransition> pvmTransitionList = activityImpl668 .getOutgoingTransitions();669if (pvmTransitionList.isEmpty()) {670return activityImpl;671 }672 }673 }674675// 根据节点ID,获取对应的活动节点676 ActivityImpl activityImpl = ((ProcessDefinitionImpl) processDefinition)677 .findActivity(activityId);678679return activityImpl;680 }681682/**683 * ********************************************************************************<br>684 * **********************以上为根据任务节点ID 获取流程各对象查询⽅法**********************<br> 685 * *********************************************************************************<br>686*/687 }。

activiti流程开发基本步骤详解

activiti流程开发基本步骤详解

activiti流程开发指南•一、BPMN•二、activiti主要接口•三、如何实现一个业务流程•四、如何管理所有流程与实例•五、开发流程•六、api一、BPMN1. 什么是BPMN首先BPMN规范是由标准组织BPMI发布的.BPMN 1.0规范发布于2004年5月。

此规范展示了BPMI组织两年多的努力成果。

BPMN的主要目标就是要提供被所有业务用户理解的一套标记语言,包括业务分析者、软件开发者以及业务管理者与监察者。

BPMN还将支持生成可执行的BPEL4WS语言。

所以,BPMN在业务流程设计与流程实现之间搭建了一条标准化的桥梁。

BPMN定义了业务流程图,其基于流程图技术,同时为创建业务流程操作的图形化模型进行了裁减。

业务流程的模型就是图形化对象的网图,包括活动(也可以说工作)和定义操作顺序的流控制。

2. BPMN基础业务流程图由一系列的图形化元素组成。

这些元素简化了模型的开发,且业务分析者看上去非常熟悉。

这些元素每个都有各自的特性,且与大多数的建模器类似。

比如,活动是矩形,条件是菱形。

应该强调的是:开发BPMN的动力就是为了在创建业务流程模型时提供一个简单的机制,同时又能够处理来自业务流程的复杂性。

要处理这两个矛盾的需求的方法就是将标记的图形化方面组织分类为特定的类别。

这里提供标记类别中的一小部分,以便业务流程图的读者可以简单地识别出元素的基本类型从而理解图形。

以下是四种基本的类型:1)流对象2)连接对象3)泳道4)人工信息BPMN2.0概要:/workclass/201206272.asp二、activiti主要接口ProcessEngine processEngine =ProcessEngines.getDefaultProcessEngine();RuntimeService runtimeService = processEngine.getRuntimeService();RepositoryService repositoryService = processEngine.getRepositoryService();TaskService taskService = processEngine.getTaskService();ManagementService managementService = processEngine.getManagementService();IdentityService identityService = processEngine.getIdentityService();HistoryService historyService = processEngine.getHistoryService();FormService formService = processEngine.getFormService();ProcessEngines.getDefaultProcessEngine()会在第一次调用时初始化并创建一个流程引擎,以后再调用就会返回相同的流程引擎。

Activiti(工作流-2)执行过程解析

Activiti(工作流-2)执行过程解析

Activiti(⼯作流-2)执⾏过程解析(转载https:///lp2388163/article/details/98206543?utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2all sobaiduend~default-1-98206543.nonecase&utm_term=activiti%20%E6%89%A7%E8%A1%8C%E9%A1%BA%E5%BA%8F&spm=1000.2123.3001.4430)1.activiti⼯作流执⾏过程解析[执⾏过程interceptor、cmd、listener、handler]1.activiti核⼼对象解释:ProcessEngine:ProcessEngines.getDefaultProcessEngine()会在第⼀次调⽤时初始化并创建⼀个流程引擎,以后再调⽤就会返回相同的流程引擎。

使⽤对应的⽅法可以创建和关闭所有流程引擎:ProcessEngines.init()和ProcessEngines.destroy()。

RepositoryService:可能是使⽤Activiti引擎时最先接触的服务。

它提供了管理和控制发布包和流程定义的操作。

它包含了⼀个流程每个环节的结构和⾏为。

可以⾃由选择把任意资源包含到发布包中。

既可以把⼀个单独的BPMN 2.0 xml⽂件放到发布包⾥,也可以把整个流程和相关资源都放在⼀起。

发布⼀个发布包,意味着把它上传到引擎中,所有流程都会在保存进数据库之前分析解析好。

TaskService:任务是由系统中真实⼈员执⾏的,所有与任务有关的功能都包含在TaskService中:查询分配给⽤户或组的任务。

创建独⽴运⾏任务。

这些任务与流程实例⽆关。

⼿⼯设置任务的执⾏者,或者这些⽤户通过何种⽅式与任务关联。

认领并完成⼀个任务。

activiti工作流数据库表详细介绍(23张表)

activiti工作流数据库表详细介绍(23张表)

activiti工作流数据库表详细介绍(23张表)Activiti的后台是有数据库的支持,所有的表都以ACT_开头。

第二部分是表示表的用途的两个字母标识。

用途也和服务的API对应。

ACT_RE_*: 'RE'表示repository。

这个前缀的表包含了流程定义和流程静态资源(图片,规则,等等)。

ACT_RU_*: 'RU'表示runtime。

这些运行时的表,包含流程实例,任务,变量,异步任务,等运行中的数据。

Activiti 只在流程实例执行过程中保存这些数据,在流程结束时就会删除这些记录。

这样运行时表可以一直很小速度很快。

ACT_ID_*: 'ID'表示identity。

这些表包含身份信息,比如用户,组等等。

ACT_HI_*: 'HI'表示history。

这些表包含历史数据,比如历史流程实例,变量,任务等等。

ACT_GE_*: 通用数据,用于不同场景下,如存放资源文件。

资源库流程规则表1) act_re_deployment 部署信息表2) act_re_model 流程设计模型部署表3) act_re_procdef 流程定义数据表运行时数据库表1) act_ru_execution运行时流程执行实例表2) act_ru_identitylink运行时流程人员表,主要存储任务节点与参与者的相关信息3) act_ru_task运行时任务节点表4) act_ru_variable运行时流程变量数据表历史数据库表1) act_hi_actinst 历史节点表2) act_hi_attachment历史附件表3) act_hi_comment历史意见表4) act_hi_identitylink历史流程人员表5) act_hi_detail历史详情表,提供历史变量的查询6) act_hi_procinst历史流程实例表7) act_hi_taskinst历史任务实例表8) act_hi_varinst历史变量表组织机构表1) act_id_group用户组信息表2) act_id_info用户扩展信息表3) act_id_membership用户与用户组对应信息表4) act_id_user用户信息表这四张表很常见,基本的组织机构管理,关于用户认证方面建议还是自己开发一套,组件自带的功能太简单,使用中有很多需求难以满足通用数据表1) act_ge_bytearray二进制数据表2) act_ge_property属性数据表存储整个流程引擎级别的数据,初始化表结构时,会默认插入三条记录,书生整理于网络。

activiti流程使用的表

activiti流程使用的表

activiti流程使用的表1. 概述在使用activiti流程引擎进行业务流程建模和执行时,需要对一系列数据库表进行管理和操作。

本文档将介绍activiti流程中使用到的主要数据库表的结构和作用。

2. 数据库表列表•ACT_RE_*:这些表主要存储流程定义和流程静态数据。

–ACT_RE_PROCDEF:存储流程定义信息,包括流程的部署信息、版本信息等。

–ACT_RE_DEPLOYMENT:存储流程部署信息,包括部署的时间、部署的用户等。

–ACT_RE_MODEL:存储模型信息,包括流程定义的设计器源码。

–ACT_RE_JOB:存储异步任务信息。

•ACT_RU_*:这些表主要存储流程实例和流程运行时的数据。

–ACT_RU_EXECUTION:存储流程实例的执行信息。

–ACT_RU_TASK:存储任务信息,包括任务的执行人、任务的状态等。

–ACT_RU_VARIABLE:存储流程实例的变量信息。

•ACT_HI_*:这些表主要存储历史数据,包括已完成流程实例、已完成任务等。

–ACT_HI_PROCINST:存储历史的流程实例信息。

–ACT_HI_TASKINST:存储历史的任务实例信息。

–ACT_HI_ACTINST:存储历史的活动实例信息。

–ACT_HI_VARINST:存储历史的变量实例信息。

3. 数据库表详细说明3.1 ACT_RE_PROCDEF表该表存储了流程定义的相关信息,包括流程定义的键、版本号、部署ID等。

字段列表:•ID_:主键ID。

•REV_:版本号。

•NAME_:流程名称。

•KEY_:流程定义的键。

•DEPLOYMENT_ID_:部署ID。

3.2 ACT_RE_DEPLOYMENT表该表存储了流程部署的相关信息,包括部署时间、部署用户等。

字段列表:•ID_:主键ID。

•NAME_:部署名称。

•DEPLOY_TIME_:部署时间。

•USER_ID_:部署用户。

3.3 ACT_RE_MODEL表该表存储了模型的相关信息,包括模型名称、模型分类、模型标识等。

工作流引擎activiti表结构和代码详解

工作流引擎activiti表结构和代码详解

工作流引擎activiti表结构和代码详解工作流引擎Activiti的表结构和代码详解Activiti是一个基于Java语言的工作流引擎,它提供了一种可执行业务流程的方式,实现了对流程进行定义、部署、执行、监控等全生命周期的管理,具有高效、灵活、可扩展等优点。

本文将详细介绍Activiti 的表结构和代码实现。

1. 表结构Activiti引擎定义了多张表,这些表按照功能可以分为以下几类:(1) 流程定义相关表ACT_GE_BYTEARRAY:流程定义和流程实例相关的二进制文件存储表,包括BPMN 2.0 XML文件和各种图片等资源文件。

ACT_RE_DEPLOYMENT:部署信息表,包含部署时间、部署后的ID 和名称。

ACT_RE_PROCDEF:流程定义信息表,包含流程ID、XML文件名、键值和流程部署ID等信息。

(2) 运行时数据表ACT_RU_EXECUTION:流程实例运行时数据表,包含流程实例ID、业务ID、当前任务ID等信息。

ACT_RU_TASK:任务运行时数据表,包含任务分配人、执行候选人、任务完成时间等信息。

(3) 历史数据表ACT_HI_PROCINST:流程实例历史数据表,包含流程实例ID、开始时间、结束时间等信息。

ACT_HI_TASKINST:任务历史数据表,包含任务分配人、执行人、开始时间等信息。

(4) 操作记录相关表ACT_HI_ACTINST:历史记录,包含流程实例ID、开始时间、结束时间等信息。

ACT_HI_COMMENT:批注表,记录了流程的操作记录和评论等信息。

2. 代码实现Activiti引擎在代码实现方面遵循了面向对象的思想和设计模式,其中核心类包括ProcessEngine、RepositoryService、RuntimeService和TaskService等。

下面通过实例代码来展示Activiti的各个组件之间的调用关系。

(1) 初始化ProcessEngineProcessEngine是Activiti引擎的核心组件,负责管理运行时数据、历史记录、任务等等。

Activiti工作流学习(二)流程实例、执行对象、任务

Activiti工作流学习(二)流程实例、执行对象、任务

Activiti⼯作流学习(⼆)流程实例、执⾏对象、任务⼀.前⾔前⾯说明了基本的流程部署、定义,启动流程实例等基本操作,下⾯我们继续来学习流程实例、执⾏对象、任务。

⼆.流程实例、执⾏对象说明整个Activiti的⽣命周期经过了如下的⼏个步骤: 1.流程部署 ---> 2.启动流程实例 --- > 3.执⾏流程对象(⼀个流程实例包含多执⾏对象) ---> 4.完成整个流程说明:三.例⼦演⽰1.完成我的任务2.查询流程状态(判断流程正在执⾏,还是结束)3.查询历史任务4.流程实例、执⾏对象、任务四.对应数据库表------------------------------------------流程实例、执⾏对象、任务--------------------------------------------------正在执⾏的执⾏对象表-- 执⾏ID_ 56 流程实例ID_ 56 流程定义ID_ _3701622B-4133-7B3D-F50F-E14B4F21E847:1:55 正在运⾏的任务定义ID_ 【可变】 USERTASKE736BEF8-4133-7B3D-F510-7B2DE7BEA8C6SELECT 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-E6D48BA60EAESELECT 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-7B2DE7BEA8C6SELECT 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/H --历史任务ID_ 74 流程实例ID_ 56 执⾏实例ID_ 56 流程定义ID_ _3701622B-4133-7B3D-F50F-E14B4F21E847:1:55 任务节点ID_ USERTASK04A84BE1-1133-7B3D-F511-1D0B7BB0A668 表单KEY_ /PAGES/HOLIDAY/HOLIDAYMANAGE/HO 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_ 74SELECT 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_ 56SELECT 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;。

activiti流程文件细解

activiti流程文件细解

Activiti流程文件细解-》Pracess(该流程的基本数据,流程名字等)-----3-》Data Objects ----------------- ------ 4-》Listeners (执仃监听器) -------------- 5-》--》Java class ---------- ------------ 6-》--》Expression -------- ------------- 6- 》--》Delegate Expression ------------ 7-》启动节点- ——8- 》--》General -------------------- ------- 8-》--》M a in config -------------- -------- 9-》--》Documentation ----------- ---------- 9- 》--》Form ----------------------- ------ 101、动态表单-------------- ----102、外置表单-------------- -----113、普通表单-------------- -----12 -》Listeners ---------------------------- —13-》任务——--14- 》!--》User Task ------------- --------- 14-》--》General -------- ------------- 14-》--》Main config--- -------------- 15-》-》Listeners -------- ----------- 16-》-》Multi instance- ------------ 16-》网关17vprocess id 二"Process" name="请假流程-普通表单” isExecutable 二"true" >vdocumentation >请假流程演示 </ documentation > </ process >流程文件:-》Pracess (该流程的基本数据,流程名字等)Process Data Objects ListenersJd最好用英文Name NamespaceC a nd i date 5ta...ms sepa rated)匚 a nd id ate s :a….nnia separated!)Documentationprocess丄血茨程的唯一标识 请噺趕■普通表单流程的名称,任意http://www. /test命名空间I 佞迭人(雰个用逗号分开》候选组(梦个用逗号分隔〕-》Data Objects (插入一条可以公用的数据)■ Det 百 propertyJT毗icin上NameTypeQKvprocess id ="myProcess" n ame="My process" isExecutable ="true" >vdocumentation >这是一个演示 </ documentation ><dataObject id ="wsy" n ame="wsy" itemSubjectRef ="xsd:stri ng" ><exte nsion Eleme nts ><activiti:value >汪诗雨 </ activiti:value > </ extensionElements ></ dataObject ></ process >Process Data Obj^etc Listener□ata prope'itieKiIJName数据2 數爲名宇-》Listeners(执行监听器)PrccebiDst 日 1 OLqechLbtcnmJava class 匕通过搭工坯口中的类*安观监听<exte nsion Eleme nts > <activiti:executio nListe ner class ="org.xdemo.example.activiti.Cdi.eve nt.ABC"<activiti:fieldname="user" ></ activiti:string > </ activiti:field></ activiti:executi on Liste ner ></ exte nsion Eleme nts >Listefter ccnfigpLiralKriiiEventTypt Delegate eiuressio-n :梢工一个且mid 隅代理的bEn Alfresco czccution scLpt: 匸兄的1AtT 禅卒Al fresco task script :定本Java class ,Expressi on ‘Delegate expressi on 以传给监听器都有域,其中的值可eve nt ="start"<activiti:str ing ><![CDATA[ HelloWord ]]> Seled;"瞬start益昕时,例輒流程启动时”逡挂阪d 结审吋4 Java das& L^prffEcian Dctlcgaui OKprssdon • Alfresco «juKuton script Alfresco task scriptB^presslon :通过亢义一个表达式IfiJkBean 的名凉可以用spring.1^5- 》--》Java class注意:class 需要实现接口org.activiti.e ngi ne.delegate.Executio nListe nervprocess id ="myProcess" n ame="My process" isExecutablevdocumentation >这是一个演示 </ documentation >vexte nsion Eleme nts> <activiti:executi on Liste nerclass 二"org.xdemo.example.activiti.Cdi.event.ABC" ></ activiti:executionListener ></ extensionElements></ process >-》--》Expression定义一个表达式类似 EL 语法。

activiti工作流表名及字段详解

activiti工作流表名及字段详解

1. activiti工作流简介activiti是一个轻量级的工作流引擎,它是一个开源的、Java语言的工作流和业务过程管理(BPM)评台。

activiti可以帮助开发者简化和优化企业的业务流程,提高工作效率,降低成本。

2. activiti工作流表名及字段详解在activiti的工作流引擎中,有一些核心的数据表用来存储流程定义、流程实例、任务等信息。

下面我们就来详细解释activiti的工作流表名及字段。

2.1 ACT_RE_*:流程存储表ACT_RE_*表是存储流程静态信息的表,包括流程定义、流程资源等。

ACT_RE_*表的常见字段包括:- ID: 唯一标识- NAME: 名称- KEY: 关键字- DEPLOYMENT_ID: 部署ID- RESOURCE_NAME: 资源名称- DGRM_RESOURCE_NAME: 流程图名称2.2 ACT_RU_*:运行时表ACT_RU_*表是存储流程运行时数据的表,包括流程实例、任务实例等。

ACT_RU_*表的常见字段包括:- ID: 唯一标识- REV: 版本号- EXECUTION_ID: 执行ID- PROC_DEF_ID: 流程定义ID- NAME: 名称- ASSIGNEE: 指派人- CREATE_TIME: 创建时间2.3 ACT_HI_*:历史数据表ACT_HI_*表是存储历史数据的表,包括流程实例的历史数据、任务的历史数据等。

ACT_HI_*表的常见字段包括:- PROC_DEF_ID: 流程定义ID- PROC_INST_ID: 流程实例ID- TASK_ID: 任务ID- START_TIME: 开始时间- END_TIME: 结束时间- DURATION: 持续时间2.4 其他表及字段在activiti工作流引擎中,还有一些其他重要的表和字段,包括ACT_ID_*表(存储用户、角色等信息)、ACT_GE_*表(存储通用的流程引擎数据)等。

Activiti工作流框架中的任务调度!工作流框架中的任务流程元素详解,使用监听器监听任务执行

Activiti工作流框架中的任务调度!工作流框架中的任务流程元素详解,使用监听器监听任务执行

Activiti⼯作流框架中的任务调度!⼯作流框架中的任务流程元素详解,使⽤监听器监听任务执⾏任务⽤户任务描述⽤户任务⽤来设置必须由⼈员完成的⼯作当流程执⾏到⽤户任务,会创建⼀个新任务,并把这个新任务加⼊到分配⼈或群组的任务列表中图形标记⽤户任务显⽰成⼀个普通任务(圆⾓矩形),左上⾓有⼀个⼩⽤户图标XML内容XML中的⽤户任务定义:id属性是必须的,name属性是可选的:<userTask id="theTask" name="Important task" />⽤户任务可以设置描述,添加documentation元素可以定义描述:<userTask id="theTask" name="Schedule meeting" ><documentation>Schedule an engineering meeting for next week with the new hire.</documentation>描述⽂本可以通过标准的java⽅法来获取:task.getDescription()持续时间任务可以⽤⼀个字段来描述任务的持续时间可以使⽤查询API来对持续时间进⾏搜索,根据在时间之前或之后进⾏搜索Activiti提供了⼀个节点扩展,在任务定义中设置⼀个表达式,这样在任务创建时就可以设置初始持续时间表达式应该是:java.util.Datejava.util.String(ISO8601格式),ISO8601持续时间(⽐如PT50M)null在流程中使⽤上述格式输⼊⽇期,或在前⼀个服务任务中计算⼀个时间.这⾥使⽤了持续时间,持续时间会基于当前时间进⾏计算,再通过给定的时间段累加: 使⽤"PT30M"作为持续时间,任务就会从现在开始持续30分钟<userTask id="theTask" name="Important task" activiti:dueDate="${dateVariable}"/>任务的持续时间也可以通过TaskService修改,或在TaskListener中通过传⼊的DelegateTask参数修改⽤户分配⽤户任务可以直接分配给⼀个⽤户,通过humanPerformer元素定义humanPerformer定义需要⼀个resourceAssignmentExpression来实际定义⽤户.⽬前只⽀持formalExpressions<process ... >...<userTask id='theTask' name='important task' ><humanPerformer><resourceAssignmentExpression><formalExpression>kermit</formalExpression></resourceAssignmentExpression></humanPerformer></userTask>只有⼀个⽤户可以作为任务的执⾏者分配⽤户在activiti中,⽤户叫做执⾏者拥有执⾏者的⽤户不会出现在其他⼈的任务列表中,只能出现执⾏者的个⼈任务列表中直接分配给⽤户的任务可以通过TaskService获取:List<Task> tasks = taskService.createTaskQuery().taskAssignee("kermit").list();任务也可以加⼊到⼈员的候选任务列表中.需要使⽤potentialOwner元素⽤法和humanPerformer元素类似,需要指定表达式中的每个项⽬是⼈员还是群组<process ... >...<userTask id='theTask' name='important task' ><potentialOwner><resourceAssignmentExpression><formalExpression>user(kermit), group(management)</formalExpression></resourceAssignmentExpression></potentialOwner></userTask>使⽤potentialOwner元素定义的任务可以通过TaskService获取:List<Task> tasks = taskService.createTaskQuery().taskCandidateUser("kermit");这会获取所有kermit为候选⼈的任务,表达式中包含user(kermit).这也会获得所有分配包含kermit这个成员的群组(⽐如,group(management),前提是kermit是这个组的成员,并且使⽤了activiti的账号组件).⽤户所在的群组是在运⾏阶段获取的, 它们可以通过IdentityService进⾏管理如果没有显式指定设置的是⽤户还是群组,引擎会默认当做群组处理下⾯的设置与使⽤group(accountancy)⼀样:<formalExpression>accountancy</formalExpression>Activiti对任务分配的扩展当分配不复杂时,⽤户和组的设置⾮常⿇烦.为避免复杂性,可以使⽤⽤户任务的⾃定义扩展assignee属性: 直接把⽤户任务分配给指定⽤户(和使⽤humanPerformer 效果完全⼀样)<userTask id="theTask" name="my task" activiti:assignee="kermit" />candidateUsers属性: 为任务设置候选⼈(和使⽤potentialOwner效果完全⼀样,不需要像使⽤potentialOwner通过user(kermit)声明,这个属性只能⽤于⼈员)<userTask id="theTask" name="my task" activiti:candidateUsers="kermit, gonzo" />candidateGroups属性: 为任务设置候选组(和使⽤potentialOwner效果完全⼀样,不需要像使⽤potentialOwner通过group(management)声明,这个属性只能⽤于群组)<userTask id="theTask" name="my task" activiti:candidateGroups="management, accountancy" />candidateUsers和candidateGroups可以同时设置在同⼀个⽤户任务中Activiti中虽然有账号管理组件和IdentityService ,账号组件不会检测设置的⽤户是否存在. Activiti允许与其他已存的账户管理⽅案集成使⽤创建事件的任务监听器来实现⾃定义的分配逻辑:<userTask id="task1" name="My task" ><extensionElements><activiti:taskListener event="create" class="org.activiti.MyAssignmentHandler" /></extensionElements></userTask>DelegateTask会传递给TaskListener的实现,通过它可以设置执⾏⼈,候选⼈和候选组public class MyAssignmentHandler implements TaskListener {public void notify(DelegateTask delegateTask) {// Execute custom identity lookups here// and then for example call following methods:delegateTask.setAssignee("kermit");delegateTask.addCandidateUser("fozzie");delegateTask.addCandidateGroup("management");...}}使⽤spring时,使⽤表达式把任务监听器设置为spring代理的bean,让这个监听器监听任务的创建事件⽰例:执⾏者会通过调⽤ldapService这个spring bean的findManagerOfEmployee⽅法获得.流程变量emp会作为参数传递给bean<userTask id="task" name="My Task" activiti:assignee="${ldapService.findManagerForEmployee(emp)}"/>可以⽤来设置候选⼈和候选组:<userTask id="task" name="My Task" activiti:candidateUsers="${ldapService.findAllSales()}"/>⽅法返回类型只能为String(候选⼈) 或Collection < String >(候选组):public class FakeLdapService {public String findManagerForEmployee(String employee) {return "Kermit The Frog";}public List<String> findAllSales() {return Arrays.asList("kermit", "gonzo", "fozzie");}}脚本任务描述脚本任务是⼀个⾃动节点当流程到达脚本任务,会执⾏对应的脚本图形标记脚本任务显⽰为标准BPMN 2.0任务(圆⾓矩形),左上⾓有⼀个脚本⼩图标XML内容脚本任务定义需要指定script和scriptFormat<scriptTask id="theScriptTask" name="Execute script" scriptFormat="groovy"><script>sum = 0for ( i in inputArray ) {sum += i}</script></scriptTask>scriptFormat的值必须兼容JSR-223(java平台的脚本语⾔).默认Javascript会包含在JDK中,不需要额外的依赖.如果要使⽤其他的脚本引擎,必须要是JSR-223引擎兼容的.还需要把对应的jar添加到classpath下, 并使⽤合适的名称:activiti单元测试经常使⽤groovygroovy脚本引擎放在groovy-all.jar中,在2.0版本之前,脚本引擎是groovy jar的⼀部分.使⽤需要添加依赖:<dependency><groupId>org.codehaus.groovy</groupId><artifactId>groovy-all</artifactId><version>2.x.x<version></dependency>脚本变量到达脚本任务的流程可以访问的所有流程变量,都可以在脚本中使⽤<script>sum = 0for ( i in inputArray ) {sum += i}</script>也可以在脚本中设置流程变量,直接调⽤execution.setVariable("variableName", variableValue) 默认,不会⾃动保存变量(activiti 5.12之前) 可以在脚本中⾃动保存任何变量,只要把scriptTask的autoStoreVariables属性设置为true 最佳实践是不要使⽤,⽽是显式调⽤execution.setVariable()<scriptTask id="script" scriptFormat="JavaScript" activiti:autoStoreVariables="false">参数默认为false: 如果没有为脚本任务定义设置参数,所有声明的变量将只存在于脚本执⾏的阶段在脚本中设置变量: 这些命名已经被占⽤,不能⽤作变量名- out, out:print, lang:import, context, elcontext.<script>def scriptVar = "test123"execution.setVariable("myVar", scriptVar)</script>脚本结果脚本任务的返回值可以通过制定流程变量的名称,分配给已存在或者⼀个新流程变量,需要使⽤脚本任务定义的'activiti:resultVariable'属性任何已存在的流程变量都会被脚本执⾏的结果覆盖如果没有指定返回的变量名,脚本的返回值会被忽略<scriptTask id="theScriptTask" name="Execute script" scriptFormat="juel" activiti:resultVariable="myVar"><script>#{echo}</script></scriptTask>脚本的结果-表达式 #{echo} 的值会在脚本完成后,设置到myVar变量中Java服务任务描述Java服务任务⽤来调⽤外部Java类图形标记Java服务任务显⽰为圆⾓矩形,左上⾓有⼀个齿轮⼩图标XML内容声明Java调⽤逻辑有四种⽅式:实现JavaDelegate或者ActivityBehavior执⾏解析代理对象的表达式调⽤⼀个⽅法表达式调⽤⼀个值表达式执⾏⼀个在流程执⾏中调⽤的类,需要在activiti:class属性中设置全类名:<serviceTask id="javaService"name="My Java Service Task"activiti:class="org.activiti.MyJavaDelegate" />使⽤表达式调⽤⼀个对象,对象必须遵循⼀些规则,并使⽤activiti:delegateExpression属性进⾏创建:<serviceTask id="serviceTask" activiti:delegateExpression="${delegateExpressionBean}" />delegateExpressionBean是⼀个实现了JavaDelegate接⼝的bean,定义在实例的spring容器中要执⾏指定的UEL⽅法表达式, 需要使⽤activiti:expression:<serviceTask id="javaService"name="My Java Service Task"activiti:expression="#{printer.printMessage()}" />⽅法printMessage()会调⽤名为printer对象的⽅法为表达式中的⽅法传递参数:<serviceTask id="javaService"name="My Java Service Task"activiti:expression="#{printer.printMessage(execution, myVar)}" />调⽤名为printer对象上的⽅法printMessage.第⼀个参数是DelegateExecution, 在表达式环境中默认名称为execution. 第⼆个参数传递的是当前流程的名为myVar的变量要执⾏指定的UEL⽅法表达式, 需要使⽤activiti:expression:<serviceTask id="javaService"name="My Java Service Task"activiti:expression="#{split.ready}" />ready属性的getter⽅法:getReady() 会作⽤于名为split的bean上.这个对象会被解析为流程对象和spring环境中的对象实现要在流程执⾏中实现⼀个调⽤的类,这个类需要实现org.activiti.engine.delegate.JavaDelegate接⼝,并在execute⽅法中提供对应的业务逻辑.当流程执⾏到特定阶段,会指定⽅法中定义好的业务逻辑,并按照默认BPMN 2.0中的⽅式离开节点⽰例: 创建⼀个java类的例⼦,对流程变量中字符串转换为⼤写这个类需要实现org.activiti.engine.delegate.JavaDelegate接⼝,要求实现execute(DelegateExecution) ⽅法,包含的业务逻辑会被引擎调⽤流程实例信息:流程变量和其他信息,可以通过DelegateExecution接⼝访问和操作public class ToUppercase implements JavaDelegate {public void execute(DelegateExecution execution) throws Exception {String var = (String) execution.getVariable("input");var = var.toUpperCase();execution.setVariable("input", var);}}serviceTask定义的class只会创建⼀个java类的实例所有流程实例都会共享相同的类实例,并调⽤execute(DelegateExecution) 类不能使⽤任何成员变量,必须是线程安全的,必须能模拟在不同线程中执⾏.影响着属性注⼊的处理⽅式流程定义中引⽤的类(activiti:class)不会在部署时实例化只有当流程第⼀次执⾏到使⽤类的时候,类的实例才会被创建如果找不到类,会抛出⼀个ActivitiException这个原因是部署环境(更确切是的classpath)和真实环境往往是不同的:当使⽤ant或业务归档上传到Activiti Explorer来发布流程,classpath没有包含引⽤的类内部实现类也可以提供实现org.activiti.engine.impl.pvm.delegate.ActivityBehavior接⼝的类实现可以访问更强⼤的ActivityExecution,它可以影响流程的流向注意: 这应该尽量避免.只有在⾼级情况下并且确切知道要做什么的情况下,再使⽤ActivityBehavior接⼝属性注⼊为代理类的属性注⼊数据. ⽀持如下类型的注⼊: 固定的字符串表达式如果有效的话,数值会通过代理类的setter⽅法注⼊,遵循java bean的命名规范(⽐如fistName属性对应setFirstName(Xxx)⽅法)如果属性没有对应的setter⽅法,数值会直接注⼊到私有属性中⼀些环境的SecurityManager不允许修改私有属性,要把想注⼊的属性暴露出对应的setter⽅法来⽆论流程定义中的数据是什么类型,注⼊⽬标的属性类型都应该是 org.activiti.engine.delegate.Expression⽰例: 把⼀个常量注⼊到属性中属性注⼊可以使⽤class属性在声明实际的属性注⼊之前,需要定义⼀个extensionElements的XML元素<serviceTask id="javaService"name="Java service invocation"activiti:class="org.activiti.examples.bpmn.servicetask.ToUpperCaseFieldInjected"><extensionElements><activiti:field name="text" stringValue="Hello World" /></extensionElements></serviceTask>ToUpperCaseFieldInjected类有⼀个text属性,类型是org.activiti.engine.delegate.Expression. 调⽤text.getValue(execution) 时,会返回定义的字符串Hello World可以使⽤长⽂字(⽐如,内嵌的email),使⽤activiti:string⼦元素:<serviceTask id="javaService"name="Java service invocation"activiti:class="org.activiti.examples.bpmn.servicetask.ToUpperCaseFieldInjected"><extensionElements><activiti:field name="text"><activiti:string>Hello World</activiti:string></activiti:field></extensionElements></serviceTask>可以使⽤表达式,实现在运⾏期动态解析注⼊的值这些表达式可以使⽤流程变量或spring定义的bean.服务任务中的java类实例会在所有流程实例中共享:为了动态注⼊属性的值,可以在org.activiti.engine.delegate.Expression中使⽤值和⽅法表达式会使⽤传递给execute⽅法的DelegateExecution参数进⾏解析<serviceTask id="javaService" name="Java service invocation"activiti:class="org.activiti.examples.bpmn.servicetask.ReverseStringsFieldInjected"><extensionElements><activiti:field name="text1"><activiti:expression>${genderBean.getGenderString(gender)}</activiti:expression></activiti:field><activiti:field name="text2"><activiti:expression>Hello ${gender == 'male' ? 'Mr.' : 'Mrs.'} ${name}</activiti:expression></activiti:field></ extensionElements></ serviceTask>⽰例: 注⼊表达式,并使⽤在当前传⼊的DelegateExecution解析:public class ReverseStringsFieldInjected implements JavaDelegate {private Expression text1;private Expression text2;public void execute(DelegateExecution execution) {String value1 = (String) text1.getValue(execution);execution.setVariable("var1", new StringBuffer(value1).reverse().toString());String value2 = (String) text2.getValue(execution);execution.setVariable("var2", new StringBuffer(value2).reverse().toString());}}可以把表达式设置成⼀个属性,⽽不是⼦元素:因为java类实例会被重⽤,注⼊只会发⽣⼀次,当服务任务调⽤第⼀次的时候发⽣注⼊当代码中的属性改变了,值也不会重新注⼊,把它们看作是不变的,不⽤修改它们服务任务结果服务流程返回的结果(使⽤表达式的服务任务)可以分配给已经存在的或新的流程变量通过指定服务任务定义的activiti:resultVariable属性来实现指定的流程变量会被服务流程的返回结果覆盖如果没有指定返回变量名,就会忽略返回结果<serviceTask id="aMethodExpressionServiceTask"activiti:expression="#{myService.doSomething()}"activiti:resultVariable="myVar" />服务流程的返回值(在myService上调⽤doSomething() ⽅法的返回值,myService可能是流程变量,也可能是spring的bean),在服务执⾏完成之后,会设置到名为myVar的流程变量⾥处理异常执⾏⾃定义逻辑时,常常需要捕获对应的业务异常,在流程内部进⾏处理抛出BPMN Errors: 在服务任务或脚本任务的代码⾥抛出BPMN error: 要从JavaDelegate,脚本,表达式和代理表达式中抛出名为BpmnError的特殊ActivitiExeption 引擎会捕获这个异常,把它转发到对应的错误处理中:边界错误事件或错误事件⼦流程public class ThrowBpmnErrorDelegate implements JavaDelegate {public void execute(DelegateExecution execution) throws Exception {try {executeBusinessLogic();} catch (BusinessException e) {throw new BpmnError("BusinessExceptionOccured");}}}构造参数是错误代码,会被⽤来决定哪个错误处理器会来响应这个错误这个机制只⽤于业务失败,应该被流程定义中设置的边界错误事件或错误事件⼦流程处理. 技术上的错误应该使⽤其他异常类型,通常不会在流程⾥处理异常顺序流: 内部实现类在⼀些异常发⽣时,让流程进⼊其他路径<serviceTask id="javaService"name="Java service invocation"activiti:class="org.activiti.ThrowsExceptionBehavior"></serviceTask><sequenceFlow id="no-exception" sourceRef="javaService" targetRef="theEnd" /><sequenceFlow id="exception" sourceRef="javaService" targetRef="fixException" />这⾥的服务任务有两个外出顺序流:分别叫exception和no-exception. 异常出现时会使⽤顺序流的ID来决定流向public class ThrowsExceptionBehavior implements ActivityBehavior {public void execute(ActivityExecution execution) throws Exception {String var = (String) execution.getVariable("var");PvmTransition transition = null;try {executeLogic(var);transition = execution.getActivity().findOutgoingTransition("no-exception");} catch (Exception e) {transition = execution.getActivity().findOutgoingTransition("exception");}execution.take(transition);}}JavaDelegate使⽤Activiti服务需要在Java服务任务中使⽤Activiti服务的场景: ⽐如,通过RuntimeService启动流程实例,⽽callActivity不满⾜需求org.activiti.engine.delegate.DelegateExecution允许通过 org.activiti.engine.EngineServices接⼝直接获得这些服务:public class StartProcessInstanceTestDelegate implements JavaDelegate {public void execute(DelegateExecution execution) throws Exception {RuntimeService runtimeService = execution.getEngineServices().getRuntimeService();runtimeService.startProcessInstanceByKey("myProcess");}}所有activiti服务的API都可以通过这个接⼝获得使⽤这些API调⽤出现的所有数据改变,都是在当前事务中在例如spring和CDI这样的依赖注⼊环境也会起作⽤,⽆论是否启⽤了JTA数据源⽰例: 下⾯的代码功能与上⾯的代码⼀致,这是RuntimeService是通过依赖注⼊获得,⽽不是通过org.activiti.engine.EngineServices接⼝@Component("startProcessInstanceDelegate")public class StartProcessInstanceTestDelegateWithInjection {@Autowiredprivate RuntimeService runtimeService;public void startProcess() {runtimeService.startProcessInstanceByKey("oneTaskProcess");}}因为服务调⽤是在当前事务⾥,数据的产⽣或改变,在服务任务执⾏完之前,还没有提交到数据库.所以API对于数据库数据的操作,意味着未提交的操作在服务任务的API调⽤中都是不可见的WebService任务描述WebService任务可以⽤来同步调⽤⼀个外部的WebService图形标记WebService任务与Java服务任务显⽰效果⼀样(圆⾓矩形,左上⾓有⼀个齿轮⼩图标)XML内容要使⽤WebService需要导⼊操作和类型,可以使⽤import标签来指定WebService的WSDL<import importType="/wsdl/"location="http://localhost:63081/counter?wsdl"namespace="/" />声明告诉activiti导⼊WSDL定义,但没有创建itemDefinition和message假设想调⽤⼀个名为prettyPrint的⽅法,必须创建为请求和响应信息对应的message和itemDefinition <message id="prettyPrintCountRequestMessage" itemRef="tns:prettyPrintCountRequestItem" /><message id="prettyPrintCountResponseMessage" itemRef="tns:prettyPrintCountResponseItem" /><itemDefinition id="prettyPrintCountRequestItem" structureRef="counter:prettyPrintCount" /><itemDefinition id="prettyPrintCountResponseItem" structureRef="counter:prettyPrintCountResponse" />在申请服务任务之前,必须定义实际引⽤WebService的BPMN接⼝和操作基本上,定义接⼝和必要的操作.对每个操作都会重⽤上⾯定义的信息作为输⼊和输出⽰例: 定义了counter接⼝和prettyPrintCountOperation操作:<interface name="Counter Interface" implementationRef="counter:Counter"><operation id="prettyPrintCountOperation" name="prettyPrintCount Operation"implementationRef="counter:prettyPrintCount"><inMessageRef>tns:prettyPrintCountRequestMessage</inMessageRef><outMessageRef>tns:prettyPrintCountResponseMessage</outMessageRef></operation></interface>然后定义WebService任务,使⽤WebService实现,并引⽤WebService操作<serviceTask id="webService"name="Web service invocation"implementation="##WebService"operationRef="tns:prettyPrintCountOperation">WebService任务IO规范每个WebService任务可以定义任务的输⼊输出IO规范<ioSpecification><dataInput itemSubjectRef="tns:prettyPrintCountRequestItem" id="dataInputOfServiceTask" /><dataOutput itemSubjectRef="tns:prettyPrintCountResponseItem" id="dataOutputOfServiceTask" /><inputSet><dataInputRefs>dataInputOfServiceTask</dataInputRefs></inputSet><outputSet><dataOutputRefs>dataOutputOfServiceTask</dataOutputRefs></outputSet></ioSpecification>WebService任务数据输⼊关联指定数据输⼊关联有两种⽅式:使⽤表达式使⽤简化⽅式使⽤表达式指定数据输⼊关联: 需要定义来源和⽬的item,并指定每个item属性之间的对应关系:<dataInputAssociation><sourceRef>dataInputOfProcess</sourceRef><targetRef>dataInputOfServiceTask</targetRef><assignment><from>${dataInputOfProcess.prefix}</from><to>${dataInputOfServiceTask.prefix}</to></assignment><assignment><from>${dataInputOfProcess.suffix}</from><to>${dataInputOfServiceTask.suffix}</to></assignment></dataInputAssociation>分配item的前缀和后缀使⽤简化⽅式指定数据输⼊关联: sourceRef元素是activiti的变量名,targetRef元素是item定义的⼀个属性:<dataInputAssociation><sourceRef>PrefixVariable</sourceRef><targetRef>prefix</targetRef></dataInputAssociation><dataInputAssociation><sourceRef>SuffixVariable</sourceRef><targetRef>suffix</targetRef></dataInputAssociation>PrefixVariable变量的值分配给prefix属性,把SuffixVariable变量的值分配给suffix属性WebService任务数据输出关联指定数据输出关联有两种⽅式:使⽤表达式使⽤简化⽅式使⽤表达式指定数据输出关联: 需要定义⽬的变量和来源表达式<dataOutputAssociation><targetRef>dataOutputOfProcess</targetRef><transformation>${dataOutputOfServiceTask.prettyPrint}</transformation></dataOutputAssociation>⽅法和数据输⼊关联完全⼀样使⽤简化⽅式指定数据输出关联: sourceRef元素是item定义的⼀个属性,targetRef元素是activiti的变量名<dataOutputAssociation><sourceRef>prettyPrint</sourceRef><targetRef>OutputVariable</targetRef></dataOutputAssociation>⽅法和数据输⼊关联完全⼀样业务规则任务描述业务规则任务⽤来同步执⾏⼀个或多个规则Activiti使⽤drools规则引擎执⾏业务规则: 包含业务规则的.drl⽂件必须和流程定义⼀起发布流程定义⾥包含了执⾏这些规则的业务规则任务流程使⽤的所有.drl⽂件都必须打包在流程BAR⽂件⾥如果想要⾃定义规则任务的实现: 想⽤不同⽅式使⽤drools,或者使⽤完全不同的规则引擎.你可以使⽤BusinessRuleTask上的class或表达式属性图形标记业务规则任务是⼀个圆⾓矩形,左上⾓使⽤⼀个表格⼩图标进⾏显⽰XML内容要执⾏部署流程定义的BAR⽂件中的⼀个或多个业务规则,需要定义输⼊和输出变量:对于输⼊变量定义,可以使⽤逗号分隔的⼀些流程变量输出变量定义只包含⼀个变量名,会把执⾏业务规则后返回的对象保存到对应的流程变量中注意: 结果变量会包含⼀个对象列表,如果没有指定输出变量名称,默认会使⽤ org.activiti.engine.rules.OUTPUT<process id="simpleBusinessRuleProcess"><startEvent id="theStart" /><sequenceFlow sourceRef="theStart" targetRef="businessRuleTask" /><businessRuleTask id="businessRuleTask" activiti:ruleVariablesInput="${order}"activiti:resultVariable="rulesOutput" /><sequenceFlow sourceRef="businessRuleTask" targetRef="theEnd" /><endEvent id="theEnd" /></process>业务规则任务也可以配置成只执⾏部署的.drl⽂件中的⼀些规则.这时要设置逗号分隔的规则名,只会执⾏rule1和rule2:<businessRuleTask id="businessRuleTask" activiti:ruleVariablesInput="${order}"activiti:rules="rule1, rule2" />定义哪些规则不⽤执⾏:除了rule1和rule2以外,所有部署到流程定义同⼀个BAR⽂件中的规则都会执⾏:<businessRuleTask id="businessRuleTask" activiti:ruleVariablesInput="${order}"activiti:rules="rule1, rule2" exclude="true" />可以⽤⼀个选项修改BusinessRuleTask的实现:<businessRuleTask id="businessRuleTask" activiti:class="${MyRuleServiceDelegate}" />BusinessRuleTask的功能和ServiceTask⼀样,但是使⽤BusinessRuleTask的图标来表⽰在这⾥要执⾏业务规则邮件任务Activiti强化了业务流程,⽀持⾃动邮件任务: 可以发送邮件给⼀个或多个参与者,包括⽀持cc,bcc,HTML内容等等邮件任务不是BPMN 2.0规范定义的官⽅任务,Activiti中邮件任务是⽤专门的服务任务实现的邮件服务器配置Activiti引擎要通过⽀持SMTP功能的外部邮件服务器发送邮件为了实际发送邮件,引擎穾知道如何访问邮件服务器.下⾯的配置可以设置到activiti.cfg.xml配置⽂件中:属性是否必须描述mailServerHost否邮件服务器的主机名(⽐如:).默认为localhostmailServerPort 是如果没有使⽤默认端⼝邮件服务器上的SMTP传输端⼝.默认为25mailServerDefaultFrom否如果⽤户没有指定发送邮件的邮件地址,默认设置的发送者的邮件地址。

activiti流程引擎表结构分析

activiti流程引擎表结构分析

activiti流程引擎表结构分析activiti5.15.0共有25张表,包括流程定义表(RE)、⼀般数据信息表(GE)、流程运⾏实例表(RU)、流程历史记录表(HI)、⽤户表(ID)、事件处理⽇志(EVT)。

Activiti的表都以ACT_开头。

第⼆部分是表⽰表的⽤途的两个字母标识。

⽤途也和服务的API对应。

ACT_RE_*: 'RE'表⽰repository。

这个前缀的表包含了流程定义和流程静态资源(图⽚,规则,等等)。

ACT_RU_*: 'RU'表⽰runtime。

这些运⾏时的表,包含流程实例,任务,变量,异步任务,等运⾏中的数据。

Activiti只在流程实例执⾏过程中保存这些数据,在流程结束时就会删除这些记录。

这样运⾏时表可以⼀直很⼩速度很快。

ACT_ID_*: 'ID'表⽰identity。

这些表包含⾝份信息,⽐如⽤户,组等等。

ACT_HI_*: 'HI'表⽰history。

这些表包含历史数据,⽐如历史流程实例,变量,任务等等。

ACT_GE_*: 通⽤数据,⽤于不同场景下。

表名说明act_evt_log事件⽇志⽂件act_ge_bytearray⼆进制数据表act_ge_property属性数据表存储整个流程引擎级别的数据,初始化表结构时,会默认插⼊三条记录act_hi_actinst历史节点表act_hi_attachment历史附件表act_hi_comment历史意见表act_hi_identitylink历史流程⼈员表act_hi_detail历史详情表,提供历史变量的查询act_hi_procinst历史流程实例表act_hi_taskinst历史任务实例表act_hi_varinst历史变量表act_id_group⽤户组信息表act_id_info⽤户扩展信息表act_id_membership⽤户与⽤户组对应信息表act_id_user⽤户信息表act_re_deployment部署信息表act_re_model流程设计模型部署表act_re_procdef流程定义数据表act_ru_event_subscr throwEvent、catchEvent时间监听信息表act_ru_execution运⾏时流程执⾏实例表act_ru_identitylink运⾏时流程⼈员表,主要存储任务节点与参与者的相关信息act_ru_job运⾏时定时任务数据表act_ru_task运⾏时任务节点表act_ru_variable运⾏时流程变量数据表。

activiti流程实例与任务

activiti流程实例与任务

activiti流程实例与任务下载温馨提示:该文档是我店铺精心编制而成,希望大家下载以后,能够帮助大家解决实际的问题。

文档下载后可定制随意修改,请根据实际需要进行相应的调整和使用,谢谢!并且,本店铺为大家提供各种各样类型的实用资料,如教育随笔、日记赏析、句子摘抄、古诗大全、经典美文、话题作文、工作总结、词语解析、文案摘录、其他资料等等,如想了解不同资料格式和写法,敬请关注!Download tips: This document is carefully compiled by theeditor. I hope that after you download them,they can help yousolve practical problems. The document can be customized andmodified after downloading,please adjust and use it according toactual needs, thank you!In addition, our shop provides you with various types ofpractical materials,such as educational essays, diaryappreciation,sentence excerpts,ancient poems,classic articles,topic composition,work summary,word parsing,copy excerpts,other materials and so on,want to know different data formats andwriting methods,please pay attention!Activiti 是一个开源的工作流引擎,它提供了一套强大的工具和 API,用于管理和执行业务流程。

activiti源码分析

activiti源码分析

ExecutionEntity内部含有parent,是一个执行树或执行路径,应该是一个流程实例的执行过程,一个实例对应一个ExecutionEntity,通过getActivity得到的是当前正在执行的activity.Activiti之流程部署:流程文件部署主要涉及到3个表,分别是:ACT_GE_BYTEARRAY、ACT_RE_DEPLOYMENT、ACT_RE_PROCDEF。

主要完成“部署包”-->“流程定义文件”-->“所有包内文件”的解析部署关系流程定义的部署需要完成如下操作:●初始化到数据库,完成三张表的插入,一个部署包里可以有N个流程定义,所以PROCDEF表内对应N条数据,BYTEARRAY表内对应N+条记录,每个xml文件一条记录,图片也会另外存放一条记录。

DEPLOYMENT内会存放一条记录●解析后的流程定义存入DeploymentCache流程部署的序列图:repositoryService DeploymentBuilder commandExecutor DeploymentManager DbSqlSession ResourceManager DeploymentCache createDeploymentexecute(new DeployCmd(deploymentBuilder))insertDeployment(DeploymentEntity)insert(DeploymentEntity)流程部署已后,启动流程时,会调用StartProcessInstanceCmd,来启动流程。

StartProcessInstanceCmd在查找ProcessDefinitionEntity时,会从deploymentCache 中查找,当cache中不存在时,会执行deploymentCache.deploy()Activiti之Query查询:缓存查询:Activiti 之manager:创建流程实例:创建流程实例:runtimeService.startProcessInstanceByKey("financialReport") 执行步骤:1.0 首先根据” financialReport”在数据库中查找流程定义2.0 查找到流程定义后,再从processDefinitionCache 中获取已经缓存的、部署完成的(xml文件被解析的)流程定义,如果processDefinitionCache 中不存在,那么执行流程的解析过程query+++++++升续 ()降续 ()list ()listPage ()Operation_5 ()singleResult ()count ()userQuery+++++userId ()userFirstName ()userEmail ()memberOfGroup ()orderByUserId ()...: userQuery : userQuery : userQuery : userQuery : userQueryCommand+execute (CommandContext context): TAbstractQuery++++++升序 ()降序 ()list ()listPage ()count ()sigleResult ()UserQueryImplTaskQueryTaskQueryImplsession ++flush ()close ()...AbstractManager++++insert (PersistentObject record)delete (PersistentObject record)getDbSqlSession ()getManager ()TaskManager++deleteTask ()findTask (): TaskEntityExecutionManager+++++deleteProcessInstances ()findProcessInstance ()findExecutions ()findChildExecutions ()findSubProcessInstance ()...: ProcessInstance : ExecutionEntity : ExecutionEntity : ExecutionEntity3.0创建流程实例代码执行过程:1.AtomicOperation:org.activiti.engine.impl.pvm.runtime.AtomicOperationProcessStart2.AtomicOperation:org.activiti.engine.impl.pvm.runtime.AtomicOperationProcessStartInitial 3.AtomicOperation:org.activiti.engine.impl.pvm.runtime.AtomicOperationActivityExecute4.ProcessInstance[805] executes Activity(theStart):org.activiti.engine.impl.bpmn.behavior.NoneStartEventActivityBehavior 5.Leaving activity 'theStart'流程启动:流程启动执行:ExecutionEntity.performOperation(AtomicOperation.PROCESS_START) ,接着执行:execution.performOperation(PROCESS_START_INITIAL);接着执行:execution.performOperation(ACTIVITY_EXECUTE);其内部执行逻辑为:ActivityBehavior activityBehavior = activity.getActivityBehavior();activityBehavior.execute(execution);activityBehavior有很多的实现类,比如:当流程启动时,启动节点的activityBehavior实际上是NoneStartEventActivityBehavior的实例。

activiti工作流程介绍

activiti工作流程介绍

1、activiti工作流简介
Alfresco软件在2010年5月17日宣布Activiti业务流程管理(BPM)开源项 目的正式启动,其首席架构师由业务流程管理BPM的专家 Tom Baeyens 担任。 Activiti项目是一项新的基于Apache许可的开源BPM平台,从基础开始 构建,旨在提供支持新的BPMN 2.0标准,包括支持对象管理组 (OMG),面对新技术的机遇,诸如互操作性和云架构,提供技术实 现。 创始人Tom Baeyens是JBoss jBPM的项目架构师,以及另一位架构师 Joram Barrez,一起加入到创建Alfresco这项首次实现Apache开源许可 的BPMN 2.0引擎开发中来。 Activiti是一个独立运作和经营的开源项目品牌,并将独立于Alfresco开 源ECM系统运行。 Activiti将是一种轻量级,可嵌入的BPM引擎,而且 还设计适用于可扩展的云架构。 Activiti将提供宽松的Apache许可2.0, 以便这个项目可以广泛被使用,同时促进Activiti BPM引擎和的BPMN 2.0的匹配,该项目现正由OMG通过标准审定。 加入Alfresco Activiti项 目的是VMware的SpringSource分支,Alfresco的计划把该项目提交给 Apache基础架构,希望吸引更多方面的 BPM专家和促进BPM的创新。
3、一个简单的流程实例
基于activiti本身的api
然后通过processEngine获得activiti各项服务
3、一个简单的流程实例
(3)、发布一个流程(最直接的方法) 同时删除一个流程过程如下
(4)、获得所有流程定义
这将会获得所有已发布的流程实例信息,如key、id、名称等。 (5)、启动一个流程实例 通过流程定义的id启动
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Activiti流程文件细解1、Process(该流程的基本数据,流程名字等) (3)1.1 Data Objects(插入一条可以公用的数据) (4)1.2 Listeners(执行监听器) (4)1.2.1 Java class (5)1.2.2 Expression (6)1.2.3 Delegate Expression (6)2、启动节点(每一个流程都有一个启动节点,此节点是流程进如的地方) (7)2.1 General (7)2.1.1 Main config (8)2.1.2 Documentation (8)2.1.3 Form(表单) (9)2.2 Listeners(执行监听器) (12)3 任务(流程中最重要的组成部分,根据业务的不同也分为很多种类型) (13)3.1 User Task (13)3.1.1 General (13)3.1.2 Main config (14)3.1.3 Listeners(任务监听器) (14)3.1.4 Multi instance(多实例)(*重要*) (15)4、网关 (15)1、activiti工作流的基本介绍1、Process(该流程的基本数据,流程名字等)-----------------------------------------------------<process id="Process" name="请假流程-普通表单" isExecutable="true"><documentation>请假流程演示</documentation></process>-----------------------------------------------------1.1 Data Objects(插入一条可以公用的数据)-----------------------------------------------------<process id="myProcess"name="My process"isExecutable="true"> <documentation>这是一个演示</documentation><dataObject id="wsy"name="wsy" itemSubjectRef="xsd:string"> <extensionElements><activiti:value>汪诗雨</activiti:value></extensionElements></dataObject></process>1.2 Listeners(执行监听器)Java class ,Expression,Delegate expression 都有域,其中的值可以传给监听器-----------------------------------------------------<extensionElements><activiti:executionListener event="start"class="org.xdemo.example.activiti.Cdi.event.ABC"><activiti:field name="user"><activiti:string><![CDATA[HelloWord]]></activiti:string></activiti:field></activiti:executionListener></extensionElements>-----------------------------------------------------1.2.1 Java class注意:class需要实现接口org.activiti.engine.delegate.ExecutionListener-----------------------------------------------------<process id="myProcess"name="My process"isExecutable="true"> <documentation>这是一个演示</documentation><extensionElements><activiti:executionListener event="start"class="org.xdemo.example.activiti.Cdi.event.ABC"></activiti:executionListener></extensionElements></process>1.2.2 Expression定义一个表达式类似EL语法。

这里的pojo是一个Bean的名称(可以用spring 代理),还可以子expression中通过计算一个表达式配置监听器的名称-----------------------------------------------------<process id="myProcess"name="My process"isExecutable="true"> <documentation>这是一个演示</documentation><extensionElements><activiti:executionListener event="end"expression="${pojo.method(executionListenerForStart)}"></activiti:executionListener></extensionElements></process>-----------------------------------------------------1.2.3 Delegate Expression这里指定的是一个spring代理的业务bean,业务bean必须实现接口:org.activiti.engine.delegate.ExecutionListener----------------------------------------------------- <process id="myProcess"name="My process"isExecutable="true"> <documentation>这是一个演示</documentation><extensionElements><activiti:executionListener event="start"delegateExpression="${aBean}"></activiti:executionListener></extensionElements></process>-----------------------------------------------------2、启动节点(每一个流程都有一个启动节点,此节点是流程进如的地方)启动时间的三种类型:1.空启动事件2.定时启动事件3.邮件启动事件4.异常启动事件*注:其中第四个异常启动事件和另为3个又不相同2.1 General-----------------------------------------------------<process id="myProcess"name="My process"isExecutable="true"> <documentation>这是一个演示</documentation><startEvent id="startevent1"name="Start"></startEvent> </process>-----------------------------------------------------2.1.1 Main config*注:Initiator:可以用来记录启动流程人的id(也可以是用户的名称)启动流程之后次属性指定的变量就会自动设置当前人的名称 .Form key:可以用来指定空启动事件关联表单----------------------------------------------------- <process id="myProcess"name="My process"isExecutable="true"> <documentation>这是一个演示</documentation><startEvent id="startevent1"name="Start"activiti:initiator="applyUserId"activiti:formKey="startUserId"></startEvent></process>-----------------------------------------------------2.1.2 Documentation----------------------------------------------------- <process id="myProcess"name="My process"isExecutable="true"> <documentation>这是一个演示</documentation><startEvent id="startevent1"name="Start"activiti:initiator="applyUserId"activiti:formKey="startUserId"></startEvent><documentation>abc</documentation> </process>-----------------------------------------------------2.1.3 Form(表单)*注:Activiti的空启动事件和任务事件都是以表单的形式提交给流程引擎作用:当我们要打开任务表单的时候可以重定向到任务表单,重定向的action如: formKey + "?id=" +objId + "&taskId=" +taskId;objId为业务对象Id,taskid为任务id,这样就可以在任务表单获取到想要的信息一般使用的表单大概有三种:1)、动态表单(在流程文件里定义)----------------------------------------------------- <process id="myProcess"name="My process"isExecutable="true"> <documentation>这是一个演示</documentation><startEvent id="startevent1"name="Start"activiti:initiator="applyUserId"activiti:formKey="startUserId"><extensionElements><activiti:formProperty id="id"name="id"type="string"expression="${leave.reason}"variable="aUser"default="abc"></activiti:formProperty></extensionElements></startEvent></procss>----------------------------------------------------- 2)、外置表单(在流程文件里定义)这种方式常用于基于工作流平台开发的方式,代码写的很少,开发人员只要把表单内容写好保存到.form文件中即可,然后配置每个节点需要的表单名称(form key),实际运行时通过引擎提供的API读取Task对应的form内容输出到页面。

相关文档
最新文档