actviti流程框架知识点

根据bpmn创建一个流程引擎

根据引擎创建相应的service

可以根据service创建一个部署对象

部署对象设置名称,加载bpmn文件资源

最后完成部署

/**
*
* @Description: TODO[]
* @param:
*
* @create: 2019年2月1日 下午4:31:10
*
* startByPIKey,可以创建一个task,在之后可以使用一个userTask返回候选人集合,此时阻塞
* 阻塞时,可以通过候选人查询出候选人可以执行的Task集合,用于返回到前端展示
* 前端通过发起Y or N ,携带taskId、userId,后台此时执行claim领取任务(关联taskId和userId,使用claim领取后,其他人不能再领取)
* claim后,对自己的特有数据库做相应操作,操作完后,执行complete(taskId)//可以携带下一步参数
*/

activiti创建数据库报错:不存在,执行了select语句

1)在activiti.cfg.xml中的url改为 //?nullCatalogMeansCurrent=true是重点
value=“jdbc:mysql://localhost:3306/test?nullCatalogMeansCurrent=true”

2)将pom.xml中的mysql驱动从8.0改成5.x
修改前:

mysql
mysql-connector-java
runtime

修改后:

mysql
mysql-connector-java
5.1.41

——————————————————————————
activiti 网关:
1.并行网关
同意将流程 分成多条分支。也能够把多条分支 汇聚到一起。
注意 并行 网关 要有2个 一个是用于 分支 一个用于 聚合
2.排他网关
当流程运行到这个网关,全部外出顺序流都会被处理一遍。 当中条件解析为true的顺序流(或者没有设置条件,概念上在顺序流上定义了一个’true’) 会 被选中,让流程继续执行。
3.包括网关
包括网关能够看做是排他网关和并行网关的结合体。 和排他网关一样,你能够在外出顺序流上定义条件。包括网关会解析它们。 可是基本的差别是包括网 关能够选择多于一条顺序流。这和并行网关一样。
4.事件网关


/*
act_re_procdef表中的key_列,是用于开启流程的key

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

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

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

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

  5. ACT_GE_*: 'GE’表示general。通用数据, 用于不同场景下,如存放资源文件。

  6. 这些表结构,还有一些辅助表。

#部署对象和流程定义相关表
#当key值相同的时候版本升级,id未key+版本+随机生成的值
SELECT * FROM act_re_deployment; #部署对象表

SELECT * FROM act_re_procdef; #流程定义表fsop

SELECT * FROM act_ge_bytearray; #资源文件表(一个存储xml,一个存储图片)

SELECT * FROM act_ge_property; #逐渐生成策略表(与Id相关)

#####################################################
#流程实例,执行对象,任务
SELECT * FROM act_ru_execution; #正在执行的执行对象表(正在执行的流程实例)

SELECT * FROM act_hi_procinst WHERE END_TIME_ IS NULL; #流程实例的历史表(一个流程实例)

SELECT * FROM act_ru_task; #正在执行的任务表(只有节点是UserTask的才有数据)

SELECT * FROM act_hi_taskinst; #任务历史表(只有节点是UserTask的时候该表存在数据)

SELECT * FROM act_hi_actinst; #所有活动节点的历史表(其中包括任务也不包括任务)
#####################################################
#流程变量
SELECT * FROM act_ru_variable;#正在执行的流程变量表

SELECT * FROM act_hi_varinst; #历史流程变量表

##################################################################
SELECT * FROM act_ru_identitylink #任务表(个人任务、组任务)

SELECT * FROM act_hi_identitylink #任务历史表

#########################################################
SELECT * FROM act_id_group #角色表

SELECT * FROM act_id_user #用户表

SELECT * FROM act_id_membership #用户角色关联表

*/


ProcessEngines.getDefaultProcessEngine().getRepositoryService().createDeployment().name(“xxx”)
.addClasspathResource(“processes/MyProcess.bpmn”)
.addClasspathResource(“processes/MyProcess.png”)
.deploy();
创建一个默认引擎,获取仓库服务RepositoryService,使用RepositoryService新建一个部署对象,为部署对象添加名字和资源文件,最后deploy()完成部署。

这一步在数据库中将操作三张表:
? ?
a)act_re_deployment(部署对象表)
? ? ? ?
存放流程定义的显示名和部署时间,每部署一次增加一条记录
? ?
注:如果部署相同Key的流程,那么Version将会升级,也就是版本升级:
? ?
启动该Key的流程时,默认启动最新版本(Version)的流程。

?
?
b)act_re_procdef(流程定义表)
? ? ? ?
存放流程定义的属性信息,部署每个新的流程定义都会在这张表中增加一条记录。
?key属性被用来区别不同的流程定义。 ?
注意:当流程定义的key相同的情况下,使用的是版本升级。 存在

version_字段,同样的流程,每部署一次,该版本号自动加1
?
c)act_ge_bytearray(资源文件表)
? ? ? ?
存储流程定义相关的部署信息。即流程定义文档的存放地。每部署一次就会增加两条记录, ? ?
? ?
一条是关于bpmn规则文件的,一条是图片的(如果部署时只指定了bpmn一个文件,activiti ? ?
? ?
会在部署时解析bpmn文件内容自动生成流程图)。两个文件不是很大,都是以二进制形式存储在数据库中。

重复部署一次,deploymentId的值以一定的形式变化
规则act_ge_property表生成


流程定义的CRUD

1.C create 增
DeploymentBuilder deploymentBuilder = processEngine.getRepositoryService().createDeployment();

			deploymentBuilder.addClasspathResource("test1.bpmn");
	
	deploymentBuilder.addClasspathResource("test1.png"); 
	Deployment

deployment = deploymentBuilder.deploy();

2.R retrieve 查
// 部署查询对象,查询表act_re_deployment

	DeploymentQuery query = processEngine.getRepositoryService().createDeploymentQuery();
	
	List<Deployment> list = query.list();
	
	for (Deployment deployment : list) {
		
		String id = deployment.getId();
		
		System.out.println(id);
	
	}

// 流程定义查询对象,查询表act_re_procdef
	
	ProcessDefinitionQuery query = processEngine.getRepositoryService()

.createProcessDefinitionQuery();
List list = query.list();

	for (ProcessDefinition pd : list) {
		
		System.out.println(pd.getName() + "" + pd.getId());
	
	}

3.U update 改

4.D delete 删
//删除部署信息
String deploymentId = “601”;

// processEngine.getRepositoryService().deleteDeployment(deploymentId);
	
processEngine.getRepositoryService().deleteDeployment(deploymentId,

true);//true,级联删除
//act_re_deployment、act_re_procdef、act_ge_bytearray,这三张表中部署ID为601的信息全部删除。

//删除流程定义(通过删除部署信息达到删除流程定义的目的)
String deploymentId = "201";
	
// processEngine.getRepositoryService().deleteDeployment(deploymentId);
		
processEngine.getRepositoryService().deleteDeployment(deploymentId,true);

说明:

1)deploymentId为流程部署ID

2)resourceName为act_ge_bytearray表中NAME_列的值

3)使用repositoryService的getDeploymentResourceNames方法可以获取指定部署下得所有文件的名称

4)使用repositoryService的getResourceAsStream方法传入部署ID和资源图片名称可以获取部署下指定名称文件的输入流

5)最后的有关IO流的操作,使用FileUtils工具的copyInputStreamToFile方法完成流程流程到文件的拷贝,将资源文件以流的形式输出到指定文件夹下。


流程:
1.start
2.serviceTask,创建一个任务(即task,自己创建的数据表中的数据)
2.接下来usertask,返回可以接取任务的人的id,activiti自动存储,此时taskId就对应了userId,一般为多(task)对多(user)或多(task)对一(user)
3.通过userid可以查询出该user对应的所有任务,List list = taskService.createTaskQuery().taskCandidateOrAssigned(userId).list();
3.指定对应的人去通过taskService.claim(taskId,userId)接取任务
4.taskService.complete(taskId,params)完成任务,执行下一步的网关,通过传的params参数执行对应的分支。


execution.setVariableLocal(“var2”, “this is userTask variable222222222!”);
runtimeService.setVariable(execution.getId(), “var”, “this is userTask variable!”);

------------PTestImpl userTask() name:yz
PTestImpl top1() name:-----------
top1(DelegateExecution execution) var:null
top1(DelegateExecution execution) var2:VariableInstanceEntity[id=2506, name=var2, type=string, textValue=this is userTask variable222222222!]

PTestImpl top2() name:-----------
top2(DelegateExecution execution) var:null
top2(DelegateExecution execution) var2:VariableInstanceEntity[id=2506, name=var2, type=string, textValue=this is userTask variable222222222!]
top2(DelegateExecution execution) var_top2:VariableInstanceEntity[id=2513, name=var_top2, type=string, textValue=this is top variable222222222!]
top2(DelegateExecution execution) runtimeService.getVariable(execution.getId(),var_top):this is top variable!
top2(DelegateExecution execution) runtimeService.getVariable(execution.getId(),var):this is userTask variable!

PTestImpl down1() name:-----------
down1(DelegateExecution execution) var:null
down1(DelegateExecution execution) var2:null

PTestImpl down2() name:-----------
down2(DelegateExecution execution) var:null
down2(DelegateExecution execution) var2:null
down2(DelegateExecution execution) var_down:null
down2(DelegateExecution execution) var_down2:VariableInstanceEntity[id=2515, name=var_down2, type=string, textValue=this is top variable222222222!]
down2(DelegateExecution execution) runtimeService.getVariable(execution.getId(),var):this is userTask variable!


使用runtimeService.setVariable(executionId, key,value)存储的元素,需使用runtimeServicegetVariable(executionId, key),executionId可通过方法传入的execution实例获取
使用execution.setVariableLocal(key,value),需使用execution.getVariableLocal(key)


总结:
同一节点下设置同一变量会覆盖之前的节点。
不同节点为同一变量名设置属性时,setVariable会覆盖同一变量名,setVariableLocal则会使用不同的id保存同一变量名下的属性值。

local的作用范围小,如果是分支execution的local变量,就只能在execution分支生存期使用。

local变量的好处是,可以在每个分支使用同名的变量

variable都是针对processInstance

global:set/getVariable;local:set/getVariableLocal()


userTask:62502
------------PTestImpl userTask() name:yz
top1:62502
down1:62511
top2:62502
down2:62511

分析:userTask和top1的executionId相同,所以导致在top对应的execution中可以取到userTask.setVariableLocal(key,Object)的值
相同原因,初步猜测与默认从上直下的执行顺序有关,第一分支即主分支,第二及之后所有分支为新建分支,拥有与主分支id不同的executionId

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值