这期内容当中小编将会给大家带来有关Activiti的知识点分析是什么,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。
查询接口中的Xxx即为各种对象的查询方式,如createProcessDefinitionQuery为查询流程定义的方法。查询最后的调用有如下通用方法:
asc:升序,和list配合使用
desc:倒序,和list配合使用
count:返回计数
list:返回一个list
listPage:返回分页list
singleResult:返回单个对象
不同的查询接口需要调用不同的服务组件,如repositoryService提供流程定义相关的查询;identityService服务组件提供用户、用户组相关的查询;runtimeService提供流程实例相关的查询。
①常规查询:如下查询为声明了一个流程定义processDefinition来接受查询返回的单个对象,流程定义需要调用repositoryService服务组件中的createProcessDefinition,根据部署的id获取,流程定义的单个实体。
ProcessDefinition processDefinition=repositoryService.createProcessDefinitionQuery(). deploymentId(deployment.getId()).singleResult();
②自定义sql查询:可以使用自定义sql去根据数据库字段查询数据:
List<Group> groups=identityService.createNativeGroupQuery().sql("SELECT * FROM ACT_ID_GROUP where NAME=#{name}").parameter("name","group2");
流程定义部署使用DeploymenBuilder对象,该对象提供了以下方法来实现流程部署:
addClasspathResource
addInputStream
addString
addZipInputStream
addBpmnModel
addBytes
deploy
如我们正常部署一个bpmn文件定义的流程定义使用如下代码:
DeploymentBuilder builder=repositoryService.createDeployment(); builder.addClasspathResource("test1.bpmn"); builder.deploy();
先使用DeploymenBuilder类来生命了一个builder对象,并通过repositoryService来创建部署,在之后使用builder的addClasspathResource方法将bpmn部署到数据库中,在此过程中该方法不仅回将bpmn文件内容存入数据库,也会根据bpmn生成对应的流程图png文件以通存入数据库。
流程定义部署完成后,还可以终止或激活流程定义,当终止流程定义时,该流程定义的流程实例不能再被启动。
//终止流程定义 repositoryService.suspendProcessDefinitionByKey(ProcessDefinitionKey); //启动流程定义 repositoryService.activateProcessDefinitionByKey(ProcessDefinitionKey);
任务候选人(组):表示该任务可以由某个用户组(如经理)来完成。
任务持有人(owner):完成该任务时某个人的职责,那么这个人是此任务的持有人,一个任务只能由一个持有人。
任务代理人(assignee):由于本人不能及时处理任务,而委托给他人,这个人就是此任务代理人,一个任务只能由一个代理人。
对任务设置候选人,使用addCandidateUser将用户设置为某个人物的候选人,并将这种绑定关系记录到ACT_RU_IDENTITYLINK表中,代码如下:
String taskId = UUID.randomUUID().toString(); //此处因为只是demo所以直接创建了一个task,正常情况下应该从流程实例中取出task Task task = ts.newTask(taskId); task.setName("测试任务"); ts.saveTask(task); // 创建用户 String userId = UUID.randomUUID().toString(); User user = is.newUser(userId); user.setFirstName("angus"); is.saveUser(user); // 设置任务的候选用户 ts.addCandidateUser(taskId, userId); //设置任务的持有用户 ts.setOwner(taskId, userId); //设置任务的代理人,只能被声明一次代理人,再次声明会报错 ts.claim(taskId, userId);
如何给任务设置参数:
//简单的任务参数保存在ACT_RU_VARIABLE表中 taskSevice.setVariable(task.id,"var1","hello"); //任务参数也可以保存一个对象,但是保存的对应类必须已经实现了serialize可序列话接口 //如果保存对象,数据即序列话后的对象将会额外保存到ACT_GE_BYTEARRAY taskSevice.setVariable(task.id,"person1",p); //取出存入的对象 Person p=taskSevice.getVariable(task.id,"person1",Person.class);
任务参数有着不同的作用域:
本地参数(setVariableLocal):当前节点完成后,参数就会失效。
全局参数(setVariable):一直有效。
除了使用java代码set参数外,还可以在流程xml文件中保存参数:
<dataObject id="personName" name="personName" itemSubjectRef="xsd:string"> <extensionElements> <activiti:value>Crazyit</activiti:value> </extensionElements> </dataObject>
获取方法如下:
String var = taskService.getVariable(task.getId(), "personName", String.class);
流程实例(ProcessInstance)可以理解为我们根据流程定义(类)而创建的“对象”。
执行流(Execution)简单理解为工作流图中的一条条线路,而流程实例继承了执行流,因此也被称为著执行流。
ProcessInstance可以直接使用runService的startProcessInstance方法开创建,创建成功后他的数据将会被保存在ACT_RU_EXECUTION表中,需要注意的是尽管流程图如图只有一根线路,数据库中也会出现两条数据,一条为主执行流,一条为子执行流。
无论工作流图是怎么样的,都必定有一个主执行流,而有多少个分支就会有多少个子执行流。
startProcessInstance主要有三类分别是根据id、key和message消息来启动,前两个就是根据流程定义的id、key来启动,最后一个消息是等待一个消息来创建流程实例。
一般流程前进使用trigger方法,使用流程的id传参
Execution exe = runService.createExecutionQuery() .processInstanceId(pi.getId()).onlyChildExecutions() .singleResult(); System.out.println(pi.getId() + ", 当前节点:" + exe.getActivityId()); // 让它往前走 runService.trigger(exe.getId()); exe = runService.createExecutionQuery() .processInstanceId(pi.getId()).onlyChildExecutions() .singleResult(); System.out.println(pi.getId() + ", 当前节点:" + exe.getActivityId());
信号事件:xml形式如下
<signal id="testSignal" name="testSignal"></signal> <process id="myProcess" name="My process" isExecutable="true"> ... <intermediateCatchEvent id="signalintermediatecatchevent1" name="SignalCatchEvent"> <signalEventDefinition signalRef="testSignal"></signalEventDefinition> </intermediateCatchEvent> ... </process>
它需要等待程序发出信号才能继续运行,不然就会在原地等待。
runService.signalEventReceived("testSignal");
消息事件:xml中需要先设定message标签,再在中间抛出事件中,创建消息事件定义,并使用messageRef属性执行message标签。
<message id="testMsg" name="testMsg"></message> <process id="myProcess" name="My process" isExecutable="true"> ... <intermediateCatchEvent id="messageintermediatecatchevent1" name="MessageCatchEvent"> <messageEventDefinition messageRef="testMsg"></messageEventDefinition> </intermediateCatchEvent> ... </process>
相应的程序中也只需要发出相应消息即可工作流继续向前进行
runService.messageEventReceived("testMsg", exe.getId());
区别:从信号和消息的方法参数就可以看出,信号的发送不需要制定特定的对象,而消息是需要制定流程的。简单来说信号像是广播,只要定义了该信号的人都会收到信号;而消息像私信只有收到消息的目标流程才会继续前行。
异步任务产生的工作:下面的应用会使用到activiti引擎的异步执行,因此需要在activiti.cfg.xml中进行如下配置,开启异步执行,如果不开启此项配置,流程将会卡在ServiceTask不能继续向前运行。
<property name="asyncExecutorActivate" value="true"></property>
之后创建bpmn工作流图,以xml格式打开,更改他的servicetask组件属性
<serviceTask id="servicetask1" name="Service Task" activiti:async="true" activiti:class="org.crazyit.act.c10.MyJavaDelegate"></serviceTask>
activti:class指向的是他要执行的类(类需要实现JavaDelegate接口并且实现execute方法),而async属性则是开启异步执行。
package org.crazyit.act.c10; import org.activiti.engine.delegate.DelegateExecution; import org.activiti.engine.delegate.JavaDelegate; public class MyJavaDelegate implements JavaDelegate { @Override public void execute(DelegateExecution arg0) { System.out.println("这是处理类"); } }
定时器任务:会等待定时结束在继续执行,如下:
<intermediateCatchEvent id="timerintermediatecatchevent1" name="TimerCatchEvent"> <timerEventDefinition> <timeDuration>PT1M</timeDuration> </timerEventDefinition> </intermediateCatchEvent>
被中断的任务:被suspend中断的任务会被写入ACT_RU_SUSPENED表中,同理activate重新激活被中断的任务,任务将会被从表中移除,恢复正常运行。
无法执行的任务:加入一个任务三次抛出异常,就将会被加入ACT_RU_DEADLETTER表中。
上述就是小编为大家分享的Activiti的知识点分析是什么了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注亿速云行业资讯频道。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。