activiti工作流简介[通俗易懂]

activiti工作流简介[通俗易懂] 工作流简介工作流定义工作流:  就是“业务过程的部分或整体在计算机应用环境下的自动化”,它主要解决的是“使在多个参与者之间按照某种预定义的规则传递文档、信息或任务的过程自动进行,从而实现某个预期的业务目标,或者促使此目标的实现”。工作流管理系统(WorkflowManagementSystem,WfMS):  工作流管理系统是一个软件系统,它完成工作量的定义…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE稳定放心使用

 

工作流简介

工作流定义

工作流:

    就是“业务过程的部分或整体在计算机应用环境下的自动化”,它主要解决的是“使在多个参与者之间按照某种预定义的规则传递文档、信息或任务的过程自动进行,从而实现某个预期的业务目标,或者促使此目标的实现”。

工作流管理系统(Workflow Management System, WfMS):

    工作流管理系统是一个软件系统,它完成工作量的定义和管理,并按照在系统中预先定义好的工作流规则进行工作流实例的执行。工作流管理系统不是企业的业务系统,而是为企业的业务系统的运行提供了一个软件的支撑环境。

    主要工作:

    1、定义工作流:包括具体的活动、规则等。

    2、执行工作流:按照流程定义的规则执行,并由多个参与者进行控制。

工作流特点

采用工作流有以下优点:

    1、提高系统的柔性,适应业务流程的变化 

    2、实现更好的业务过程控制,提高顾客服务质量

    3、降低系统开发和维护成本

常见工作流:Activiti、JBPM、OSWorkflow、ActiveBPEL、YAWL等。

activiti工作流

activiti简介

Activiti5是由Alfresco软件在2010年5月17日发布的业务流程管理(BPM)框架,它是覆盖了业务流程管理、工作流、服务协作等领域的一个开源的、灵活的、易扩展的可执行流程语言框架。

Activiti基于Apache许可的开源BPM平台,创始人Tom Baeyens是JBoss Activiti的项目架构师。

activiti工作流简介[通俗易懂]

工作流引擎

ProcessEngine对象是Activiti工作的核心。负责生成流程运行时的各种实例及数据、监控和管理流程的运行,其他的类都是由他而来。

产生方式:

首先需要先创建Activiti配置对象的实例ProcessEngineConfiguration,里面主要配置相关数据源参数,支持基于配置文件和注解的创建。

 

然后通过ProcessEngineConfiguration创建工作流引擎,举例如下(这里列举基于spring的SpringProcessEngineConfiguration作为ProcessEngineConfigurationImpl的配置实现):

ProcessEngine processEngine =  springProcessEngineConfiguration.buildProcessEngine();

ProcessEngine 可以产生RepositoryService、RuntimeService、TaskService等服务类。举例如下:

RepositoryService repositoryService =  processEngine.getRepositoryService();

各个Service的作用:

RepositoryService

管理流程定义

RuntimeService

执行管理,包括启动、推进、删除流程实例等操作

TaskService

任务管理

HistoryService

历史管理(执行完的数据的管理)

IdentityService

组织机构管理

FormService

一个可选服务,任务表单管理

ManagerService

 

 

RepositoryService

    RepositoryService是Activiti的仓库服务类,用于定义、部署和配置流程。

RuntimeService

    RuntimeService是activiti的流程执行服务类。可以从这个服务类中获取很多关于正在执行的流程相关的信息。

TaskService

    TaskService是activiti的流程任务服务类。可以从这个类中获取任务的信息。

HistoryService

    HistoryService是activiti的查询历史信息的类。在一个流程执行完成后,这个对象为我们提供查询历史信息。

Deployment

    部署对象,用于部署流程定义文件(bpmn、png等文件),也可对流程进行修改和删除。

ProcessDefinition

    流程定义类,解析.bpmn后得到的流程定义规则的信息,工作流系统就是按照流程定义的规则执行的,通常用于查询部署的流程定义和资源。

ProcessInstance

    ProcessInstance代表流程定义的执行实例。如A请了一天的假,他就必须发出一个流程实例的申请。一个流程实例包括了所有的运行节点。我们可以利用这个对象来了解当前流程实例的进度等信息。

流程实例就表示一个流程从开始到结束的最大的流程分支,即一个流程中流程实例只有一个。

Execution

    执行对象。Activiti用这个对象去描述流程执行的每一个节点。一个流程中,执行对象可以存在多个,但是流程实例只能有一个。在单线流程中,Execution就是同ProcessInstance,在多线流程中,分线路中每个活动代表Execution。如下图的示例:

activiti工作流简介[通俗易懂]

BPMN

activiti基于BPMN规范引入了很多组件,下面列出一些常用的组件模块。

start事件

首先解释一下事件:事件用于对发生在流程生命周期的事情进行建模。事件总是被形象成一个圆圈。在 BPMN 2.0 中,存在两种主要的事件类型:捕获事件和抛出事件。

       捕获:流程执行到该事件时,会等待事件触发。事件触发类型由内部图标或 XML 中的类型声明来定义。捕获事件视觉上可以通过里面没有填充的内部图标与抛出事件进行区分(也就是说,图标是白色的)。
       抛出:流程执行到该事件时,事件就会被触发。该事件触发的类型由内部图标或 XML 中的类型声明来定义。抛出事件视觉上可以通过内部图标与抛出的事件进行区分,抛出事件的图标使用黑色填充。

start 事件表示流程的开始。定义了流程如何被启动的 start 事件类型。start 事件总是捕获型的,start事件通常包括,none start事件和timer start事件。

none start事件不需要触发器就能发生,一般通过调用 startProcessInstanceByXXX 方法启动流程实例的时候触发。none start 事件被形象化成不带内图标的圆(即,没有触发器类型)。如下图:

activiti工作流简介[通俗易懂]

XML表示:

<startEvent id="start" name="my start event" />

 

timer start 事件用于在给定的时间点创建流程实例。它可以用在只启动一次的流程中,也可以用在特定时间间隔下启动的流程。其图标被形象话为有表的内图标的圆,如下图:

activiti工作流简介[通俗易懂]

XML表示(示例为从2017年3月11日12:13开始,流程将启动4次每次间隔5分钟):

<startEvent id="theStart">
<timerEventDefinition>
<timeCycle>R4/2017-03-11T12:13/PT5M</timeCycle>
</timerEventDefinition>
</startEvent>

end事件

结束事件表明流程或子流程(执行路径)的结束。结束事件总是抛出型的。这意味着当流程执行到结束事件时,有一个结果会被抛出。结果的类型是以事件的内部黑色图标来表示的。end事件包括None end事件和error end事件。none end即正常结束事件。error end事件当流程执行到error end事件时,会结束当前的执行路径,并抛出 error。Error可以被与之匹配的中间边界error事件捕获。如果没有找到匹配的边界error事件,默认会使用none end事件。如下图是none end事件:

activiti工作流简介[通俗易懂]

XML表示:

<endEvent id="end" name="my end event" />

顺序流(sequence flow)

顺序流是两个流程元素的连接器。一个元素在流程执行期间被访问后,流程会沿着该元素所有输出的顺序流继续执行。顺序流上也可带条件一般结合gateway使用。图标如下所示:

activiti工作流简介[通俗易懂]

XML表示:

<sequenceFlow id="flow1" sourceRef="theStart" targetRef="theTask" />

排他网关(Exclusive Gateway)

也叫单一网关,用来对流程中的决定进行建模。流程执行到这种gateway时,按照输出流定义的顺序对它们进行计算。条件为 true 的顺序流(或没有设置条件,概念上顺序流上定义为’true’)被选取继续执行流程。

注意:在多个顺序流条件为true 的情况下,XML 中最先定义的那个被选取来继续流程的执行(仅有那个会被选中)。如果没有选取到任何顺序流,就会抛出异常。

如下图所示:

activiti工作流简介[通俗易懂]

 

XML表示:

<exclusiveGateway id="exclusiveGw" name="Exclusive Gateway" />
<sequenceFlow id="flow2" sourceRef="exclusiveGw" targetRef="theTask1">
<conditionExpression xsi:type="tFormalExpression">${input == 1}</conditionExpression>
</sequenceFlow>
<sequenceFlow id="flow3" sourceRef="exclusiveGw" targetRef="theTask2">
<conditionExpression xsi:type="tFormalExpression">${input == 2}</conditionExpression>
</sequenceFlow>
<sequenceFlow id="flow4" sourceRef="exclusiveGw" targetRef="theTask3">
<conditionExpression xsi:type="tFormalExpression">${input == 3}</conditionExpression>
</sequenceFlow>

并行网关(Parallel Gateway)

Parallel gateway能拆分出多个执行路径,或多个输入执行路径进行合并,通常先通过拆分的网关拆分成多个并行的顺序流,然后再通过合并网关进行合并:

    拆分(fork):并行执行所有的输出顺序流,为每一个顺序流创建一个并行执行路径。
    合并(join):所有到达 parallel gataway 的并发性的执行路径都等待于此,直到每个输入流都执行到。然后,流
程经由 joining gateway 继续向下执行。

如下图所示:

activiti工作流简介[通俗易懂]

上例中,XML表示:

<parallelGateway id="myParallelGateway" />
<startEvent id="theStart" />
<sequenceFlow id="flow1" sourceRef="theStart" targetRef="fork" />
<parallelGateway id="fork" />
<sequenceFlow sourceRef="fork" targetRef="receivePayment" />
<sequenceFlow sourceRef="fork" targetRef="shipOrder" />
<userTask id="receivePayment" name="Receive Payment" />
<sequenceFlow sourceRef="receivePayment" targetRef="join" />
<userTask id="shipOrder" name="Ship Order" />
<sequenceFlow sourceRef="shipOrder" targetRef="join" />
<parallelGateway id="join" />
<sequenceFlow sourceRef="join" targetRef="archiveOrder" />
<userTask id="archiveOrder" name="Archive Order" />
<sequenceFlow sourceRef="archiveOrder" targetRef="theEnd" />
<endEvent id="theEnd" />
 

用户任务(User Task)

用户任务用来对那些需要人参与完成的工作进行建模。当流程执行到这样的用户任务时,会在分配任务的用户或用户组的任务列表中创建新的任务。

如下图所示:

activiti工作流简介[通俗易懂]

XML表示:

<userTask id="inspector_downpayment_approve_task" name="包卖付款审核" activiti:candidateGroups="inspector_downpayment_approve">
  <documentation>包卖付款审核</documentation>
</userTask>

 

 

数据库

ACT_RE_*: ‘RE’表示repository。 这个前缀的表包含了流程定义和流程静态资源 (图片,规则,等等)。

ACT_RU_*: ‘RU’表示runtime。 这些运行时的表,包含流程实例,任务,变量,异步任务,等运行中的数据。 Activiti只在流程实例执行过程中保存这些数据, 在流程结束时就会删除这些记录。 这样运行时表可以一直很小速度很快。

ACT_ID_*: ‘ID’表示identity。 这些表包含身份信息,比如用户,组等等。

ACT_HI_*: ‘HI’表示history。 这些表包含历史数据,比如历史流程实例, 变量,任务等等。

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

表摘要如下:

表类型 表名 描述
ACT_EVT ACT_EVT_LOG 事件日志表
ACT_GE_* ACT_GE_BYTEARRAY 二进制数据表,存储流程定义相关的部署信息。即流程定义文档的存放地。每部署一次就会增加两条记录,一条是关于bpmn规则文件的,一条是图片的(如果部署时只指定了bpmn一个文件,activiti会在部署时解析bpmn文件内容自动生成流程图)。两个文件都是以二进制形式存储在数据库中
ACT_GE_PROPERTY 属性数据表,存储整个流程引擎级别的数据,初始化表结构时,会默认插入三条记录。
ACT_HI_* ACT_HI_ACTINST 历史节点表,存放历史所有完成的活动。
ACT_HI_ATTACHMENT 历史附件表
ACT_HI_COMMENT 历史意见表
ACT_HI_DETAIL 历史详情表,提供历史变量的查询
ACT_HI_IDENTITYLINK 历史流程人员表,存储任务的办理人,包括个人任务和组任务,表示历史任务
ACT_HI_PROCINST 历史流程实例表,存储已经执行完的历史流程实例信息
ACT_HI_TASKINST 历史流程任务表,存储已经执行完的历史任务信息
ACT_HI_VARINST 历史变量表,存储已经执行完的历史流程变量信息
ACT_ID_* ACT_ID_GROUP 用户组信息表
ACT_ID_INFO 用户扩展信息表
ACT_ID_MEMBERSHIP 用户与用户组关系信息表
ACT_ID_USER 用户信息表
ACT_RE_* ACT_RE_DEPLOYMENT 部署信息表,存放流程定义的显示名和部署时间
ACT_RE_MODEL 流程设计模型部署表,存储流程定义的数据信息。
ACT_RE_PROCDEF 流程定义数据表,存放流程定义的属性信息,部署每个新的流程定义都会在这张表中增加一条记录。注意:当流程定义的key相同的情况下,使用的是版本升级
ACT_RU_* ACT_RU_EVENT_SUBSCR throwEvent、catchEvent时间监听信息表
ACT_RU_EXECUTION 运行时流程执行对象表,当流程达到一个节点中时,会在执行对象表中产生一条数据,当流程结束后,流程实例将会在正在执行的执行对象表中被删除
ACT_RU_IDENTITYLINK 运行时流程人员表,主要存储任务的办理人,包括个人任务和组任务,表示正在执行的任务
ACT_RU_JOB 运行时定时任务数据表
ACT_RU_TASK 运行时任务节点表,当流程达到一个节点中时,会在执行对象表中产生一条数据,如果当前节点是用户任务节点,这时也会在用户任务节点表中增加一条记录,当流程结束后,流程实例将会在正在执行的任务节点表中被删除
ACT_RU_VARIABLE 运行时流程变量数据表,设置流程变量的时候,向act_ru_variable这个表添加数据

流程的定义、管理、执行和部署

流程的定义和部署

    流程的定义、部署、查询、和删除的代码示例如下:

@Autowired
private ProcessEngine processEngine;
/**部署流程定义*/
@Test
public void deploy(){
    String bpmnClassPath = "bpmn/test_process.bpmn20.xml";
    Deployment deployment = processEngine.getRepositoryService()
            .createDeployment()
            .addClasspathResource(bpmnClassPath)
            .deploy();
    System.out.println(deployment.getId()+"        "+deployment.getName());
}
/**查看流程定义*/
@Test
public void queryProcessDefinition() throwsException {
	//获取仓库服务对象,使用版本的升序排列,查询列表
	List<ProcessDefinition> pdList = processEngine.getRepositoryService().createProcessDefinitionQuery()
	//添加查询条件
	//.processDefinitionKey(processDefinitionKey)
	//排序
	.orderByProcessDefinitionVersion().asc().list();//查询的结果集
	//遍历集合,查看内容
	for(ProcessDefinition pd : pdList) {
		System.out.println("id:" + pd.getId());
		System.out.println("name:" + pd.getName());
		System.out.println("key:" + pd.getKey());
		System.out.println("version:" + pd.getVersion());
		System.out.println("resourceName:"+pd.getDiagramResourceName());
		System.out.println("***************************************");
	}
}
@Test
public void deleteDeployment() throws Exception {
	//删除发布信息
	String deploymentId = "1";
	//获取仓库服务对象
	RepositoryService repositoryService = processEngine.getRepositoryService();
	//普通删除,如果当前规则下有正在执行的流程,则抛异常
	//repositoryService.deleteDeployment(deploymentId);
	//级联删除,会删除和当前规则相关的所有信息,正在执行的信息,也包括历史信息
	//相当于:repositoryService.deleteDeploymentCascade(deploymentId);
	repositoryService.deleteDeployment(deploymentId,true);
}

流程实例、任务的执行

    启动流程实例、查询流程任务、办理任务的代码示例如下:

/*启动流程实例*/
@Test
public void startProcess() throws Exception {
	//通过流程定义的key启动流程,会启动版本最高的流程
	ProcessInstance pi = processEngines.getRuntimeService()//获取正在执行的Service
	.startProcessInstanceByKey("myProcess");//按照流程定义的key启动流程实例,默认按照最新版本启动
	System.out.println("pid:" + pi.getId() +",activitiId:" + pi.getActivitiId()+",pdId:"+pi.getProcessDefinitionId());
}
/*查看个人任务*/
@Test
public void startProcess() throws Exception {
	//配置查询对象
	String assignee="张三";
	//创建任务查询对象,查询个人任务
	List<Task> list = processEngine.getTaskService().createTaskQuery().taskAssignee(assignee)//指定个人任务的办理人查询任务
	.orderByTaskCreateTime().desc()//按照任务创建时间升序排列
	.list();//查询任务的所有记录
	System.out.println("======================【"+assignee+"】的个人任务列表=================");
	for(Task task: list) {
		System.out.print("id:"+task.getId()+",");
		System.out.print("name:"+task.getName()+",");
		System.out.print("createTime:"+task.getCreateTime()+",");
		System.out.println("assignee:"+task.getAssignee());
	}
}
/*办理任务*/
@Test
public void complete() throws Exception {
	String taskId = "1102";
	//完成任务
	processEngine.getTaskService().complete(taskId);//指定任务ID,完成任务
}
 

流程变量

流程变量指流程实例中可能存在变化的量,比如请假流程中有请假天数、请假原因等一些参数都为流程变量的范围。如下图所示:

activiti工作流简介[通俗易懂]

/**设置流程变量*/
@Test
public void setVariables(){
	//获取执行的Service
	TaskService taskService = processEngine.getTaskService();
	//指定办理人
	String assigneeUser = "张三";
	//流程实例ID
	String processInstanceId = "1701";
	Task task = taskService.createTaskQuery().taskAssignee(assigneeUser)//指定办理人
	.processInstanceId(processInstanceId)//指定流程实例ID
	.singleResult();
	/**一:变量中存放基本数据类型*/
	//taskService.setVariable(task.getId(), "请假人","李四");//使用流程变量的名称和流程变量的值设置流程变量,一次只能设置一个值
	//taskService.setVariable(task.getId(), "请假天数",3);
	//taskService.setVariable(task.getId(), "请假日期",new Date());
	/**二:变量中存放javabean对象,前提:让javabean对象实现implements
	java.io.Serializable*/
	Person p = new Person();
	p.setId(1L);
	p.setName("王五");
	taskService.setVariable(task.getId(), "人员信息",p);
	/**三:也可设置多个参数
	taskService.setVariables(taskId, variablesMap);
}

用户管理

主要包括创建用户,创建组,以及建立组和用户的关系。具体用的数据库表包括:

act_id_group:角色组表

act_id_user:用户表:

act_id_membership:用户角色表

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/185378.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • Oracle insert into太慢

    Oracle insert into太慢insertinto太慢insertinto太慢?Roger带你找真凶运营商客户的计费库反应其入库程序很慢,应用方通过监控程序发现主要慢在对于几个表的insert操作上。按照我们的通常理解,insert应该是极快的,为什么会很慢呢?而且反应之前挺好的。这有点让我百思不得其解。通过检查event也并没有发现什么奇怪的地方,于是我通过10046跟踪了应用的入库程序,如下应用方反应比较慢…

  • 什么是RESTful API

    什么是RESTful API

  • 计算机二级公共基础知识点整理

    计算机二级公共基础知识点整理1流程图箭头表示控制流 2结构化程序设计:自顶向下,逐步求精,模块化,限制使用goto语句 3堆排序O(nlog2n)比较次数最少,其他都是n(n-1)2 4栈先进先出的原则 5E-R图转换关系模型是逻辑设计阶段6ASII码为7位,所有大写ASII码都小于小写字母 7系统总线包括数据总线,控制总线和地址总线 8存储在RAM中的数

  • 免费数据集下载网站【dataset】

    免费数据集下载网站【dataset】https://github.com/awesomedata/awesome-public-datasets转载于:https://www.cnblogs.com/jerrybaby/p/9293319.html

  • 快速查看Linux系统版本

    快速查看Linux系统版本终端输入命令:lsb_release-a

  • java分布式(分布式架构)「建议收藏」

    java分布式(分布式架构)「建议收藏」【声明:版权所有,欢迎转载,请勿用于商业用途。联系信箱:feixiaoxing@163.com】开头的话,架构多半和业务关联在一起,如果只是简单的图书管理系统、选课系统或者什么简单的财务系统,用不着分布式。只有大型公司、高并发的业务才需要分布式的帮助。当然,架构本身要和业务模型紧密配合才能发挥作用。很长一段时间,java都是最流行的编程语言。我想,一方面…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号