2019独角兽企业重金招聘Python工程师标准>>>
1、因为我用的是eclipse,所以介绍一下eclipse安装activiti的方法,help——>Install new software,如下图:
点击add
会出现如下图:
安装图示输入,点击ok,然后finish,等待安装完成。
2、使用
创建一个项目:新建MyProcess.bpmn文件,代码如下:
activiti视图如下:
pom文件需要添加如下几个包:
activiti有两种监听器,分别是:ExecutionListern主要用于流程的开始、结束和连线的监听,共有三个值:"start"、"end"、"take",其中start和end用于整个流程的开始和结束,take用于连线。TaskListern主要用于节点的监听,共有四个事件:分别是:"create"、"assignment"、"complete"、"delete",当流转到这个节点是触发create事件,当被委托是触发assignment事件,当事件完成时, 因为activity会删除相应数据表中的节点信息所以会同时触发complete和delete事件。
项目中用到的四个监听器代码如下:
/***@description executionListern主要用于流程的开始、结束和连线的监听* 共有三个值:"start"、"end"、"take"。* 其中start和end用于整个流程的开始和结束,take用于连线*@auth panmingshuai*@time 2018年4月5日下午8:59:16* */public class MyExecutionListern implements ExecutionListener{/*** */private static final long serialVersionUID = 1L;@Overridepublic void notify(DelegateExecution execution) throws Exception {//得到现在事件阶段的值,用"start".endsWith(eventName)来判断String eventName = execution.getEventName();if("start".endsWith(eventName)){System.out.println("-------------------流程开始-------------------");} else if("end".equals(eventName)){System.out.println("-------------------流程结束-------------------");}}
}
/***@description *@auth panmingshuai*@time 2018年4月5日下午11:18:24* */public class MyTaskListernBegin implements TaskListener {/*** */private static final long serialVersionUID = 1L;@Overridepublic void notify(DelegateTask delegateTask) {//得到现在事件阶段的值,用"create".endsWith(eventName)来判断String eventName = delegateTask.getEventName();if("create".equals(eventName)){System.out.println("-------------------分组任务开始---------------");//指定组任务审核人员delegateTask.addCandidateUser("ming1");delegateTask.addCandidateUser("ming2");} else if("complete".equals(eventName)){System.out.println("-------------------分组任务结束---------------");}}}
/***@description taskListern主要用于节点的监听* 共有四个事件:分别是:"create"、"assignment"、"complete"、"delete"。* 当流转到这个节点是触发create事件,当被委托是触发assignment事件,当事件完成时,* 因为activity会删除相应数据表中的节点信息所以会触发complete和delete事件*@auth panmingshuai*@time 2018年4月5日下午8:59:16* */public class MyTaskListernGroup implements TaskListener {/*** */private static final long serialVersionUID = 1L;@Overridepublic void notify(DelegateTask delegateTask) {//得到现在事件阶段的值,用"create".endsWith(eventName)来判断String eventName = delegateTask.getEventName();if("create".equals(eventName)){System.out.println("-------------------分组任务开始---------------");//指定组任务审核人员delegateTask.addCandidateUser("ming1");delegateTask.addCandidateUser("ming2");} else if("complete".equals(eventName)){System.out.println("-------------------分组任务结束---------------");}}}
/***@description *@auth panmingshuai*@time 2018年4月5日下午9:44:16* */public class MyTaskListernOwern implements TaskListener {/*** */private static final long serialVersionUID = 1L;@Overridepublic void notify(DelegateTask delegateTask) {//得到现在事件阶段的值,用"create".endsWith(eventName)来判断String eventName = delegateTask.getEventName();if("create".equals(eventName)){System.out.println("-------------------个人任务开始---------------");//添加个人任务delegateTask.setOwner("ming1");} else if("complete".equals(eventName)){System.out.println("-------------------个人任务结束---------------");}}}
接下来是activiti的配置,因为activiti需要操作数据表,因此如果要使用activiti必须要配置数据库连接池和事物管理:
对于其中activiti的服务接口的作用如下:
RepositoryService 管理流程定义
RuntimeService 执行管理,包括启动、推进、删除流程实例等操作
TaskService 任务管理
HistoryService 历史管理(执行完的数据的管理)
具体使用时需要注入相应的接口:
当然可以不使用这些接口使用processEngine的各种get方法也可以,只是不怎么方便:
3、具体的业务使用:
3.1、首先如果要使用工作流,必须先部署流程:
// 部署流程,只要是符合BPMN2规范的XML文件,理论上都可以被ACTIVITI部署Deployment deployment = repositoryService.createDeployment().addClasspathResource("org/pan/activity/bpmn/MyProcess.bpmn").deploy();System.out.println("deployment: id: " + deployment.getId() + "----- name: " + deployment.getName());return "发布成功";
注:项目启动时,activiti会自动在你连接的数据库生成它所需要的数据表,都是以act_打头的。
一般如果没改流程图的话,也没改数据库的话,只用部署一次就够了。
现在假设一个人提交了一个申请过来,怎么给他一个流程的实例呢?如下:
//开启流程时设置的变量是全局变量Map
这便开启了一个专属的流程实例给某一个业务,值得注意的是processInstance.getId()这个id是activiti自己生成的id,businessId是我们自己的业务id,但是这个可以不用设置,这看项目的需要,我们可以拥有自己的业务申请表,但是也可以把申请的内容放到variables中,需要的时候再查出来,这样就不用再建立自己的申请表了。
流程开始了就需要处理任务了,但是有谁来处理任务呢?
上面的监听器里其实就有代码,需要注意的是当任务的creat事件被触发时设置处理人,设置的处理人也只能处理这个任务,当然还有其他设置处理人的方式,但是我觉得这种方式最好。另外delegateTask.addCandidateUser("ming1");这个是设置组任务处理人的。
delegateTask.setOwner("ming1");这个是设置个人任务的。所谓的组任务是指这个组里的人都会看到这个任务,个人任务是指只有这个人会看到这个任务。
任务处理人设置好了,那一个人怎么看到自己的任务呢?
// 个人任务查询List
// 组任务查询List
需要注意的一点是组任务查询时,只要是这个组的组员的人都会看到所有的组任务,但是组任务怎么确定是谁来处理的这个任务呢?这个时候就需要将这个任务指定了,比如说一个组员说这个任务归他了,那个我们就得把任务派发给他,不然不知道是谁搞定的。如下指定:
taskService.claim(taskId, userName);
好了任务也查好了,我该怎么处理呢:
String val = (String) taskService.getVariable(taskId, "isTrue");String shuai = (String) taskService.getVariable(taskId, "shuai");System.out.println(shuai);System.out.println(val);//这里设置的变量是局部变量,只对下一个节点有用Map
这里的getVariable方法是获取从上一个节点传过来的参数,taskService调用complete方法完成节点,这个时候会触发该节点的complete和delete事件以及下一个节点的create事件。complete方法中的variables是传到下一个节点的参数。需要特别注意的是,启动流程实例时startProcessInstanceByKey方法中的variables参数是全局的,你可以在任意一个节点调到他们的值。其中有一个用处就是:比如你要限制一个申请被打回的次数,你可以用它。
好了任务完成了,我们怎么看这个流程走到了哪里呢?
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceBusinessKey(businessId).singleResult();Task activityTask = taskService.createTaskQuery().processInstanceId(processInstance.getId()).taskDefinitionKey(processInstance.getActivityId()).singleResult();System.out.print("----- activityTaskName: " + activityTask.getName());System.out.println("----- isEnded:" + processInstance.isEnded());return "查询成功";
其中activityTask即为当前流程所在的任务节点。
那怎么查一个任务经历了哪些节点呢?
HistoricProcessInstance processInstance = historyService.createHistoricProcessInstanceQuery().processInstanceBusinessKey(businessId).singleResult();List
怎么查一个人处理了哪些任务呢?
List
基本上一个项目中就用到了这些流程的功能,基本满足了,完毕