13、Activiti7工作流从入门到放弃
1、工作流介绍
1、工作流简介
- 工作流(Workflow),就是通过计算机对业务流程自动化执行管理。它主要解决的是“使在多个参与者之间按照某种预定义的规则自动进行传递文档、信息或任务的过程,从而实现某个预期的业务目标,或者促使此目标的实现”。
2、使用案例
- 出差费用报销流程、请假流程、采购单审批流程等。
3、使用行业
- 制造业,电信服务业,银证险等金融服务业,物流服务业,物业服务业,物业管理,大中型进出口贸易公司等。
4、应用场景、
- 企业: 采购流程、合同审核流程
- 客户: 客户电话投诉处理流程
- 生活中: 住房贷款审批流程、办理身份证、办理准生手续
- 行政: 出差审批、报销流程、请假审批、用车流程、会议室申请
- 银行业: 信贷审批、信用卡发卡审批
- 人事: 员工培训、绩效考核、职位变动
5、传统的实现方式
- 需要在发起申请的时候选择每个阶段由哪个人员进行审批(数据库需要记录)
- 需要在数据库中设计一个状态的字段【主管审批0,总经理审批1,财务审批2】,主管审批通过之后把状态修改为总经理审批.(硬编码的方式)
- 当流程处于主管审批时,只有角色为主管的用户才能看到这条审核数据.
6、工作流引擎简介
- 是一种按照预定义规则【需要符合BPMN规范】进行部署,将业务和节点的流程进行分离【特定形式进行关联】,实现节点的自动流转的工作流框架.
7、工作流引擎工作图示
2、什么是Activiti7
1、简介
- Alfresco 软件在 2010 年 5 月 17 日宣布 Activiti 业务流程管理(BPM)开源项目的正式启动, 其首席架构师由业务流程管理 BPM 的专家 Tom Baeyens 担任, Tom Baeyens 就是原来 jbpm 的架构师,而 jbpm 是一个非常有名的工作流引擎,当然 activiti 也是一个工作流引擎。
- Activiti 是一个工作流引擎, activiti 可以将业务系统中复杂的业务流程抽取出来,使用专门的建模语言(BPMN2.0)进行定义,业务系统按照预先定义的流程进行执行,实现了业务系统的业务流程由 activiti 进行管理,减少业务系统由于流程变更进行系统升级改造的工作量,从而提高系统的健壮性,同时也减少了系统开发维护成本。
2、官网
- 官方网站
3、核心机制
- 业务流程图要规范化,需要遵守一套标准。
- 业务流程图本质上就是一个XML文件,而XML可以存放所要的数据。
- 读取业务流程图的过程就是解析XML文件的过程。
- 读取一个业务流程图的结点就相当于解析一个XML的结点,进一步将数据插入到MySQL表中,形成一条记录。
- 将一个业务流程图的所有节点都读取并存入到MySQL表中。
- 后面只要读取MySQL表中的记录就相当于读取业务流程图的一个节点。
- 业务流程的推进,后面就转换为读取表中的数据,并且处理数据,结束的时候这一行数据就可以删除了。
4、BPMN简介
- BPMN(Business Process Model And Notation),业务流程模型和符号,是由BPMI(BusinessProcess Management Initiative)开发的一套的业务流程建模符号,使用BPMN提供的符号可以创建业务流程。2004年5月发布了BPMN1.0规范。BPMI于2005年9月并入OMG(The ObjectManagement Group,对象管理组织)组织。OMG于2011年1月发布BPMN2.0的最终版本。
- Activit就是使用BPMN2.0进行流程建模、流程执行管理,它包括很多的建模符号。
5、Activiti如何使用
1、整合Activiti
- Activiti是一个工作流引擎,业务系统使用Activiti来对系统的业务流程进行自动化管理,为了方便业务系统访问(操作)Activiti的接口或功能,通常将Activiti和业务系统的环境集成在一起。
2、业务建模
- 使用Activiti流程建模工具(Activity-designer)定义业务流程(.bpmn文件)。
3、部署业务流程
- 使用Activiti提供的API向Activiti中部署.bpmn文件(一般情况下还需要一起部署业务流程的图片.png)。
4、启动流程实例
- 启动一个流程实例表示开始一次业务流程的运行。每个流程实例互不影响,如同Java中的对象一样。
5、查询待办任务
- 因为现在系统的业务流程已经交给Activiti管理,通过Activiti就可以查询当前流程执行到哪里了,当前用户需要办理什么任务。
6、处理待办任务
- 用户查询待办任务后,就可以办理某个任务,如果这任务办理完成还需要其他用户办理,比如采购单创建后由部门经理审核,这个过程也是由Activiti帮我们完成
7、结束流程
- 当任务办理完成没有下一个任务/结点了,这个流程实例就完成了。
3、Activiti7环境要求
1、开发环境
- Jdk1.8或以上版本
- Mysql 5及以上的版本
- Tomcat8.5
- IDEA
- Activiti 7.0.0.SR1
2、IDEA中安装流程设计器
3、解决流程编辑器中文乱码
在IDEA的安装目录的bin目录下将idea.exe.vmoptions和idea64.exe.vmoptions两个文件末尾添加-Dfile.encoding=UTF-8
- 重启IDEA
4、SpringBoot集成Activiti7
1、创建Maven项目
2、导入相关依赖
<properties><slf4j.version>1.6.6</slf4j.version><log4j.version>1.2.12</log4j.version><activiti.version>7.0.0.SR1</activiti.version></properties><dependencies><!-- activiti引擎 --><dependency><groupId>org.activiti</groupId><artifactId>activiti-engine</artifactId><version>${activiti.version}</version></dependency><!-- 整合Spring --><dependency><groupId>org.activiti</groupId><artifactId>activiti-spring</artifactId><version>${activiti.version}</version></dependency><!-- bpmn 模型处理 --><dependency><groupId>org.activiti</groupId><artifactId>activiti-bpmn-model</artifactId><version>${activiti.version}</version></dependency><!-- bpmn 转换 --><dependency><groupId>org.activiti</groupId><artifactId>activiti-bpmn-converter</artifactId><version>${activiti.version}</version></dependency><!-- bpmn json数据转换 --><dependency><groupId>org.activiti</groupId><artifactId>activiti-json-converter</artifactId><version>${activiti.version}</version></dependency><!-- bpmn 布局 --><dependency><groupId>org.activiti</groupId><artifactId>activiti-bpmn-layout</artifactId><version>${activiti.version}</version></dependency><!-- mysql驱动 --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.40</version></dependency><!-- mybatis --><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.4.5</version></dependency><!-- 链接池 --><dependency><groupId>commons-dbcp</groupId><artifactId>commons-dbcp</artifactId><version>1.4</version></dependency><!-- 单元测试 --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version></dependency><!-- log start --><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>${log4j.version}</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>${slf4j.version}</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>${slf4j.version}</version></dependency><!-- log end --><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.6</version></dependency><!--数据库连接池--><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.2.4</version></dependency></dependencies>
3、添加日志配置
- 在
resources
下创建log4j.properties
,内容如下:
# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE debug info warn error fatal
log4j.rootCategory=debug, CONSOLE, LOGFILE
# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r[%15.15t] %-5p %30.30c %x - %m\n
# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=./activiti.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r[%15.15t] %-5p %30.30c %x - %m\n
4、添加核心配置文件
- 在
resource
目录中添加配置文件activiti.cfg.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"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/contex
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd"><!--数据库连接池--><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="com.mysql.jdbc.Driver" /><!--如果数据库中中文出现了乱码,在路径后面添加数据库字符集使用utf-8--><property name="url" value="jdbc:mysql:///activiti" /><property name="username" value="" /><property name="password" value="" /></bean><!-- 默认id对应的值 为processEngineConfiguration --><bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration"><property name="dataSource" ref="dataSource"/><!--activiti数据库表处理策略false(默认值):检查数据库的版本和依赖库的版本,如果不匹配就抛出异常true:构建流程引擎时,执行检查,如果需要就执行更新。如果表不存在,就创建。create-drop:构建流程引擎时创建数据库报表,关闭流程引擎时就删除这些表。drop-create:先删除表再创建表。create:构建流程引擎时创建数据库表,关闭流程引擎时不删除这些表--><property name="databaseSchemaUpdate" value="true"/></bean>
</beans>
5、初始化数据表测试
@Testpublic void testInit(){ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();System.out.println(processEngine);}
【测试结果】:
【注意事项:】
- 初始化之前必须在数据库中创建数据库activiti
- 如果数据库中中文出现了乱码,在路径后面添加数据库字符集使用utf-8
5、Activiti7入门使用
1、业务建模(也叫流程定义)
- 在resources目录下新建一个文件件bpmn文件夹,新建一个bpmn文件为myleave.bpmn
1、绘制业务流程图
2、部署流程定义
- 1、需要使用的service是RepositoryService
- 2、需要传递参数为文件路径
- 3、主要涉及到的表有:
- ACT_GE_PROPERTY 引擎属性表
- ACT_RE_PROCDEF 流程定义表
- ACT_RE_DEPLOYMENT 流程部署表
- ACT_GE_BYTEARRAY 二进制资源表
- ACT_GE_PROPERTY 引擎属性表
代码实例
@Testpublic void testActiviti7Deploy() {// 1、获取流程引擎对象ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();// 2、获取仓库的serviceRepositoryService repositoryService = processEngine.getRepositoryService();// 3、调用api进行部署Deployment deploy = repositoryService.createDeployment()// 创建部署对象.addClasspathResource("bpmn/myleave.bpmn")// 添加流程定义文件.deploy();// 调用api进行部署// 获取部署后的部署idSystem.out.println("流程定义部署id为:" + deploy.getId());}
执行结果
3、启动流程实例
- 1、需要使用的service是RuntimeService
- 2、需要传递流程定义的key,也就是业务建模是定义的id
- 3、主要涉及的表有:
- ACT_HI_TASKINST 历史任务表
- ACT_HI_PROCINST 历史流程实例表
- ACT_HI_ACTINST 历史活动信息表
- ACT_HI_IDENTITYLINK 历史身份连接表
- ACT_RU_EXECUTION 运行时执行实例表
- ACT_RU_TASK 运行时任务表
- ACT_RU_IDENTITYLINK 运行时身份连接表
- ACT_HI_TASKINST 历史任务表
代码示例:
@Testpublic void testActivity7Start() {// 获取流程引擎对象ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();// 获取运行时serviceRuntimeService runtimeService = defaultProcessEngine.getRuntimeService();// 获取仓库serviceRepositoryService repositoryService = defaultProcessEngine.getRepositoryService();// 根据部署id查询流程实例ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId("1")// 部署后会返回一个部署id和部署时间在部署详情表中可以查看.singleResult();// 获取keyString key = processDefinition.getKey();// 启动流程ProcessInstance leaveProcess = runtimeService.startProcessInstanceByKey(key);System.out.println("流程实例的id为:" + leaveProcess.getId());}
运行结果:
4、查询待办任务
- 1、使用的service是TaskService
- 2、需要传递参数为任务的负责人
- 3、主要涉及表有:
- ACT_RU_TASK 运行时任务表
- ACT_RE_PROCDEF 流程定义表
- ACT_RU_TASK 运行时任务表
代码示例:
@Testpublic void testActivitiSelectTask() {// 获取流程引擎对象ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();// 获取任务的serviceTaskService taskService = defaultProcessEngine.getTaskService();// 查询指定用户的待办任务String userId = "张三";Task task = taskService.createTaskQuery().taskAssignee(userId).singleResult();System.out.println("张三的待办任务有:" + task);}
执行结果:
5、任务处理
- 1、使用service为TaskService
- 2、需要参数任务负责人
- 3、相关数据表有
- ACT_GE_PROPERTY 引擎属性表
- ACT_HI_TASKINST 历史任务表
- ACT_HI_ACTINST 历史活动信息表
- ACT_HI_IDENTITYLINK 历史身份连接表
- ACT_RU_TASK 运行时任务表
- ACT_RU_IDENTITYLINK 运行时身份连接表
- ACT_RU_EXECUTION 运行时执行实例表
- ACT_HI_TASKINST 历史任务表
- ACT_RU_TASK 运行时任务表
代码示例:
@Testpublic void testActivitiDoTask() {// 获取流程引擎对象ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();// 获取任务serviceTaskService taskService = defaultProcessEngine.getTaskService();// 根据流程实例id和任务负责人查询任务列表List<Task> list = taskService.createTaskQuery().processInstanceId("5001").taskAssignee("张三").list();// 执行任务list.forEach(task -> {taskService.complete(task.getId());System.out.println(task.getAssignee() + " 完成了 " + task.getName() + "任务");});}
执行结果:
6、添加任务批注
- 1、任务批注的添加只需要在任务执行之前调用方法进行添加
- 2、需要传递参数:
- 1、任务id
- 2、任务的流程实例id
- 3、批注内容
@Testpublic void testAddCommentBeforeTask() {// 获取流程引擎对象ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();// 获取任务serviceTaskService taskService = defaultProcessEngine.getTaskService();// 根据流程实例id和任务负责人查询任务列表List<Task> list = taskService.createTaskQuery().processInstanceId("5001").taskAssignee("李四").list();// 执行任务list.forEach(task -> {taskService.addComment(task.getId(), task.getProcessInstanceId(), "请假时间过长!");taskService.complete(task.getId());System.out.println(task.getAssignee() + " 完成了 " + task.getName() + "任务");});}
7、历史任务查询
代码示例:
@Testpublic void testHistoryTask() {// 获取流程引擎对象ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();// 获取历史serviceHistoryService historyService = defaultProcessEngine.getHistoryService();// 获取任务serviceTaskService taskService = defaultProcessEngine.getTaskService();// 查询历史任务信息List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery().processInstanceId("2501").list();list.forEach(taskInstance -> {System.out.println(taskInstance.getName());// 获取历史批注信息taskService.getTaskComments(taskInstance.getId()).forEach(comment -> {System.out.println(comment.getFullMessage());});});}
8、历史审批的查询
@Testpublic void testSelectHistoryTask() {//流程实例IDString processInstanceId = "2501";//任务审核人String taskAssignee = "李四";//创建ProcessEngine对象ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();//获取historyServiceHistoryService historyService = processEngine.getHistoryService();//获取taskServiceTaskService taskService = processEngine.getTaskService();//获取历史审核信息List<HistoricActivityInstance> list = historyService.createHistoricActivityInstanceQuery().activityType("userTask")//只获取用户任务.processInstanceId(processInstanceId).taskAssignee(taskAssignee).finished().list();for (HistoricActivityInstance instance : list) {System.out.println("任务名称:" + instance.getActivityName());System.out.println("任务开始时间:" + instance.getStartTime());System.out.println("任务结束时间:" + instance.getEndTime());System.out.println("任务耗时:" + instance.getDurationInMillis());//获取审核批注信息List<Comment> taskComments =taskService.getTaskComments(instance.getTaskId());if (taskComments.size() > 0) {System.out.println("审批批注:" + taskComments.get(0).getFullMessage());}}}
6、Activiti7进阶
1、流程定义相关
1、流程定义查询
代码示例:
@Testpublic void testQueryDefinition() {//获取流程引擎对象ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();// 获取仓库的serviceRepositoryService repositoryService = defaultProcessEngine.getRepositoryService();// 查询流程定义List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery().list();list.forEach(processDefinition -> {System.out.println("流程定义ID:" + processDefinition.getId());System.out.println("流程定义名称:" + processDefinition.getName());System.out.println("流程定义key:" + processDefinition.getKey());System.out.println("流程定义版本:" + processDefinition.getVersion());System.out.println("流程资源文件名称:" + processDefinition.getResourceName());System.out.println("部署对象id:" + processDefinition.getDeploymentId());});}
执行结果:
2、流程定义资源下载
代码示例:
public void testDownloadResource() throws Exception {//创建ProcessEngine对象ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();//获取仓库服务RepositoryService repositoryService = processEngine.getRepositoryService();//获取流程定义集合List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery().processDefinitionKey("leaveProcess").orderByProcessDefinitionVersion()//按照版本排序.desc()//降序.list();//获取最新那个ProcessDefinition definition = list.get(0);//获取部署IDString deploymentId = definition.getDeploymentId();//获取bpmn的输入流InputStream bpmnInput = repositoryService.getResourceAsStream(deploymentId, definition.getResourceName());//获取png的输入流InputStream pngInput = repositoryService.getResourceAsStream(deploymentId, definition.getDiagramResourceName());//设置bpmn输入FileOutputStream bpmnOutPut = new FileOutputStream("D:/leave.bpmn");//设置png输入FileOutputStream pngOutPut = new FileOutputStream("D:/leave.png");IOUtils.copy(bpmnInput, bpmnOutPut);IOUtils.copy(pngInput, pngOutPut);}
3、流程定义删除
代码示例:
public void testDeleteDefinition() {//获取流程引擎对象ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();// 获取仓库的serviceRepositoryService repositoryService = defaultProcessEngine.getRepositoryService();// 删除流程定义// 该流程定义下没有正在运行的流程实例可以直接删除// 参数true表示顺带删除对应的流程实例repositoryService.deleteDeployment("1", true);}
2、流程实例相关
1、流程实例简介
【简介】: 流程实例其实就是指用户或程序按照定义好的流程定义发起一个流程,发起的该流程就叫做流程实例。对应我们的流程启动。
【图解流程定义与流程实例】:
2、业务标识
【问题提出】: 当用户发起一个请假流程的时候,审批人需要查看用户发起请假的信息该如何获取到该信息,此时就需要我们绑定业务标识(BusinessKey)
【绑定业务标识】:
- 1、启动流程的时候指定业务标识,会将业务标识存存储在act_run_execution表中
- 2、业务标识的要求必须和流程实例时一一对应的。因此一般会把业务表中的主键作为流程实例启动时的业务标识。
【图解业务标识】:
代码示例:
@Testpublic void testActivity7Start() {// 获取流程引擎对象ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();// 获取运行时serviceRuntimeService runtimeService = defaultProcessEngine.getRuntimeService();// 获取仓库serviceRepositoryService repositoryService = defaultProcessEngine.getRepositoryService();// 根据部署id查询流程实例ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId("1").singleResult();// 获取keyString key = processDefinition.getKey();// 模拟业务标识String businessKey = "8001";// 启动流程并传入业务标识ProcessInstance leaveProcess = runtimeService.startProcessInstanceByKey(key,businessKey);System.out.println("流程实例的id为:" + leaveProcess.getId());}
执行结果:
处理任务时获取业务标识:
@Testpublic void testActivitiDoTask() {// 获取流程引擎对象ProcessEngine defaultProcessEngine = ProcessEngines.getDefaultProcessEngine();// 获取任务serviceTaskService taskService = defaultProcessEngine.getTaskService();// 获取运行时serviceRuntimeService runtimeService = defaultProcessEngine.getRuntimeService();// 根据流程实例id和任务负责人查询任务列表List<Task> list = taskService.createTaskQuery().processInstanceId("10001").taskAssignee("张三").list();// 执行任务list.forEach(task -> {// 根据当前任务的流程实例id查询流程实例信息获取业务标识ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult();String businessKey = processInstance.getBusinessKey();taskService.complete(task.getId());System.out.println(task.getAssignee() + " 完成了 " + task.getName() + "任务。" + "业务标识为:" + businessKey);});}
执行结果:
3、流程定义/实例的挂起与激活
全部流程实例挂起使用场景:
- 流程发生变更的时候
- 流程过程中某个节点出错的时候
- 业务流程发生改变,已经发起的流程实例继续按照旧的流程走,如果新发起的流程就按照新的业务流程走.这时候我们就需要挂起流程定义,但是不挂起流程实例
单个流程实例挂起场景:
- 评分流程:可设置多级评分,评分流程会按照从上往下的顺序,
- 依次评分;评分人必须在评分截至时间内完成评分,否则不允许继续评分,流程将会挂起,停止流转;
主要涉及方法:
- 挂起流程定义
// 参数1 :流程定义id ,参数2:是否暂停流程实例,参数3:激活时间
repositoryService.suspendProcessDefinitionById(processDefinitionId,true,null);
- 激活流程定义
// 参数1 :流程定义id ,参数2:是否暂停流程实例,参数3:激活时间
repositoryService.activateProcessDefinitionById(processDefinitionId,true,null);
- 挂起流程实例
runtimeService.suspendProcessInstanceById(processInstanceId);
- 激活流程实例
runtimeService.activateProcessInstanceById(processInstanceId);
3、任务分配负责人
1、固定分配
2、UEL表达式分配
主要涉方法:
- 参数封装
Map<String,Object> variables = new HashMap<String, Object>();
variables.put("assignee0","zhangsan");
variables.put("assignee1","lisi");
- 启动流程实例的时候加入审核人
//根据流程定义的key启动流程实例,这个key是在定义bpmn的时候设置的
ProcessInstanceinstance=runtimeService.startProcessInstanceByKey("leaveProcess",variables);
4、流程变量
1、什么是流程变量
- 流程变量在Activiti中是一个非常重要的角色,流程运转有时需要靠流程变量,业务系统和Activiti结合时少不了流程变量,流程变量就是Activiti在管理工作流时根据管理需要而设置的变量。
注意:虽然流程变量中可以存储业务数据,可以通过Activiti的API查询流程变量从而实现查询业务据,但是不建议这么使用,因为业务数据查询由业务系统负责,Activiti设置流程变量是为了流程执行要而创建的。
2、流程变量类型
3、流程变量作用域
- global变量: 流程变量的作用域范围的默认值是流程实例,作用域范围最大。
- local变量 : : 流程变量的作用域范围如果仅仅针对一个任务或一个执行实例,那么作用域范围没有流程实例大
4、流程变量使用方法
- 在属性上使用UEL表达式 例如:我们在审批人属性上使用UEL表达式的时候就是属性使用。
- 在连线上使用UEL表达式 例如:在请假流程中根据请假天数选择审批路线。
5、使用global变量控制流程
- 同样在启动流程的时候采用设置审核人的方式设置流程变量
【注意事项】:
- 如果UEL表达式中流程变量名不存在则报错。
- 如果如果UEL表达式都不符合条件,流程报错。
- 如果连接不设置条件/条件都满足,每个连线都会走.
5、网关
1、排他网关
- 排他网关(ExclusiveGateway)(异或网关或基于数据的排他网关),用来在流程中实现决策。当流程执行到这个网关的时候,所有分支都会判断条件是否为true,如果为true则执行该分支。
2、并行网关
- 并行网关(InclusiveGateway)允许将流程分成多条分支,也可以把多条分支汇聚到一起,并行网关的功能是基于进入和外出的顺序流的。
- 并行网关不会解析条件。即使顺序流中定义了条件,也会被忽略
3、包含网关
6、springBoot集成Activiti7(web环境下)
1、在pom文件中添加SpringBoot集成Activiti7的依赖
<!--添加activiti和SpringBoot整合的依赖MyBatis版本会有冲突,所以需要排除-->
<dependency><groupId>org.activiti</groupId><artifactId>activiti-spring-boot-starter</artifactId><version>7.0.0.SR1</version><exclusions><exclusion><artifactId>mybatis</artifactId><groupId>org.mybatis</groupId></exclusion></exclusions>
</dependency>
<!--activiti可以绘制流程的的依赖-->
<dependency><groupId>org.activiti</groupId><artifactId>activiti-image-generator</artifactId><version>7.0.0.SR1</version>
</dependency>
2、配置application.yml
配置文件
spring:activiti:database-schema-update: truedb-history-used: truehistory-level: fullcheck-process-definitions: falseuse-strong-uuids: false
- database-schema-update属性
- flase:默认值。activiti在启动时,对比数据库表中保存的版本,如果没有表或者版本不匹配,将抛出异常
- true:activiti会对数据库中所有表进行更新操作。如果表不存在,则自动创建
- create_drop: 在activiti启动时创建表,在关闭时删除表(必须手动关闭引擎,才能删除表
- drop-create: 在activiti启动时删除原来的旧表,然后在创建新表(不需要手动关闭引擎)
- db-history-used
- 检测历史表是否存在 activiti7默认没有开启数据库历史记录,true启动数据库历史记录
- history-level
- #记录历史等级 可配置的历史级别有none, activity, audit, full
- 1.none:不保存任何的历史数据,因此,在流程执行过程中,这是最高效的。
- 2.activity:级别高于none,保存流程实例与流程行为,其他数据不保存。
- 3.audit:除activity级别会保存的数据外,还会保存全部的流程任务及其属性。audit为history的默认值。
- 4.full:保存历史数据的最高级别,除了会保存audit级别的数据外,还会保存其他全部流程相关的细节数据,包括一些流程参数等。
- check-process-definitions
- #校验流程文件,默认校验resources下的processes文件夹里的流程文件
- use-strong-uuids
- 是否使用UUID作为主键生成策略
3、注意事项
- Activiti7默认和Spring Security集成了,但是我们的项目中使用的是Shiro,所以我们需要在项目中排除掉Spring Security的自动装配配置,否则我们的登录页会被覆盖。
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class,SecurityAutoConfiguration.class,ManagementWebSecurityAutoConfiguration.class
})
13、Activiti7工作流从入门到放弃相关推荐
- Activiti7 工作流引擎入门
Activiti7 工作流引擎入门 做课目的 一.适用人群: 普通人 不是每个人都能进入一线互联网大厂 BATJ 普通人,省城,软件公司,银行.政府做 二.适用项目:OA CRM ERP 系统 出差报 ...
- 【Aactiviti7 从入门到放弃】(一)Activiti7工作流引擎入门
目录 4.3 SpringBoot2与Activiti7整合 官方文档 https://activiti.gitbook.io/activiti-7-developers-guide/getting- ...
- Git从入门到放弃的Day10
点我下载电子版 文章目录 一.git简介 二.GIt的诞生 三.集中式和分布式区别 四.安装git,创建版本,git命令的使用 五.创建分支.合并分支(小试) 六.图文展示创建分支与合并分支原理 七. ...
- python ** 运算符_Python从入门到放弃运算符(2)
摘要:上一篇Python从入门到放弃-运算符(1),讲了Python的运算符中的算术运算符.赋值运算符.比较(关系)运算符,这篇继续讲Python的运算符. 逻辑运算符 逻辑运算符是对真和假两种布尔值 ...
- python从入门到放弃系列恶搞短片-太惨!学Python方法用错,直接从入门到放弃!...
原标题:太惨!学Python方法用错,直接从入门到放弃! 从你开始学习编程的那一刻起,就注定了以后所要走的路-从编程学习者开始,依次经历实习生.程序员.软件工程师.架构师.CTO等职位的磨砺:当你站在 ...
- Redis从入门到放弃系列(一) String
Redis从入门到放弃系列(一) String 本文例子基于:5.0.4 字符串是Redis中最常见的数据结构,底层是采用SDS,是可以修改的字符串,类似ArrayList,采用预分配冗余空间的方式来 ...
- hex editor怎么搜索代码_代码审计从入门到放弃(三) phplimit
原创: 一叶飘零 合天智汇 前言 接着前面的代码审计从入门到放弃(一) & function.代码审计从入门到放弃(二) & pcrewaf 本次是phplimit这道题,本篇文章提供 ...
- 从入门到放弃,.net构建博客系统(二):依赖注入
文章目录:<从入门到放弃,.net构建博客系统> 从入门到放弃,.net构建博客系统(一):系统构建 从入门到放弃,.net构建博客系统(二):依赖注入 上一篇中有讲到项目启动时会进行io ...
- k8s dashboard_【大强哥-k8s从入门到放弃02】Kubernetes1.17部署Dashboard2.0
号外号外,后面所有提升视频都会更新到知乎和B站上去,不会直接发群里了,哈哈,能看懂这句话的我都认识,大家可以先关注一下,我知乎上的所有文档也会录成视频 更多视频详见 杨哥天云:https://spac ...
最新文章
- 通过java反射机制获取该类的所有属性类型、值。
- VTK:几何对象之ParametricSuperEllipsoid
- 人族机器人叉兵_星际争霸兵种体积和伤害判断:叉叉小体积为什么运输机占2单位?...
- linux下简单的备份的脚本 2 【转】
- 荣耀Magic4 Pro延迟上市:全新一代LTPO超级四曲面屏加持
- 【Hadoop篇】--Hadoop常用命令总结
- Finders Keepers-freecodecamp算法题目
- 分布式事务中常见的三种解决方案
- PHP array_splice
- Java 继承 小练习
- shellcode之简单的栈溢出实验
- 软件质量保证基本知识加复习建议
- cwm oracle,ORA-06512: at OLAPSYS.CWM2_OLAP_UTILITY
- 读《怎样解题:数学思维的新方法》有感
- 极路由 安装php,极路由B70刷固件详细步骤说明
- 世预赛:12强赛首战国足0-3不敌澳大利亚,下一场面对日本队国足会如何调整?
- Openerp管理权限的方法
- ibatis的isequal_ibatIS中的isNotNull、isEqual、isEmpty
- 双十一的“后方战场”,闲鱼和转转吃饱了吗?
- Python Lost connection to MySQL server during query