您的位置:首页 > 其它

Activiti介绍(二):Activiti建表,执行操作流程

2018-01-30 00:00 204 查看
上次说道Activiti集成了Maven环境,这次用Activiti来跑一下项目。

一、新建项目

新建一个简单Activiti项目,如下图所示:

项目结构



在项目结构中,需要在resource里放入activiti.cfg.xml文件,此文件是activiti的配置文件,利用此配置文件可以构造关于Activiti的24张表,Activiti中的所有操作都是在这24张表之中进行的。有两种构建方式可以配置activiti.cfg.xml。如下:

activiti.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <!--
ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration
.createStandaloneProcessEngineConfiguration();
// 连接数据库的配置
processEngineConfiguration.setJdbcDriver("com.mysql.jdbc.Driver");
processEngineConfiguration
.setJdbcUrl("jdbc:mysql://localhost:3306/testactiviti?useUnicode=true&characterEncoding=utf8");
processEngineConfiguration.setJdbcUsername("****");
processEngineConfiguration.setJdbcPassword("****");
// Activiti的24个表不存在则自动创建
processEngineConfiguration
.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
-->
<bean id="processEngineConfiguration"
class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
<property name="jdbcDriver" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/testactiviti?useUnicode=true&characterEncoding=utf8"></property>
<property name="jdbcUsername" value="****"></property>
<property name="jdbcPassword" value="****"></property>
<property name="databaseSchemaUpdate" value="true"></property>
</bean>
</beans>


二、画流程图

现在开始设计一个流程,可以用activiti插件中的图标bpmn绘制工具,使用方法,新建-->other-->Activiti Diagram-->选择你需要绘制的路径,这里,我们将其放在了resource目录下面的diagrams之中了。



建好bpmn文件之后,开始绘图,使用右侧的绘图工具绘制一个流程图。



绘制好基本图形了,分别对每个元素进行属性设置,这里可以更改属性中的General的Name值,以及Main-config下面的Assignee值(办理人)。这样,每个流程都有自己的名称,ID,和办理人了,这就是一个完整的流程。保存此流程,就可以在其目录下生成一张相同名称的png流程图片,打开图片,即是自己绘制的流程示意图。



当然,这个bpmn文件也可以不使用Activiti视图打开,可以使用xml浏览器方式进行打开,出现的是xml结构的流程说明,在这里,我贴上自己的bpmn文件结构记录:

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
<process id="helloworld" name="helloworldName" isExecutable="true">
<startEvent id="startevent1" name="Start"></startEvent>
<endEvent id="endevent1" name="End"></endEvent>
<userTask id="usertask1" name="提交申请" activiti:assignee="张三"></userTask>
<userTask id="usertask2" name="部门经理审批" activiti:assignee="李四"></userTask>
<userTask id="usertask3" name="总经理审批" activiti:assignee="王五"></userTask>
<sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow>
<sequenceFlow id="flow2" sourceRef="usertask1" targetRef="usertask2"></sequenceFlow>
<sequenceFlow id="flow3" sourceRef="usertask2" targetRef="usertask3"></sequenceFlow>
<sequenceFlow id="flow4" sourceRef="usertask3" targetRef="endevent1"></sequenceFlow>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_helloworld">
<bpmndi:BPMNPlane bpmnElement="helloworld" id="BPMNPlane_helloworld">
<bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
<omgdc:Bounds height="35.0" width="35.0" x="130.0" y="30.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
<omgdc:Bounds height="35.0" width="35.0" x="130.0" y="420.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1">
<omgdc:Bounds height="55.0" width="105.0" x="95.0" y="100.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask2" id="BPMNShape_usertask2">
<omgdc:Bounds height="55.0" width="105.0" x="95.0" y="200.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask3" id="BPMNShape_usertask3">
<omgdc:Bounds height="55.0" width="105.0" x="95.0" y="300.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
<omgdi:waypoint x="147.0" y="65.0"></omgdi:waypoint>
<omgdi:waypoint x="147.0" y="100.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
<omgdi:waypoint x="147.0" y="155.0"></omgdi:waypoint>
<omgdi:waypoint x="147.0" y="200.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
<omgdi:waypoint x="147.0" y="255.0"></omgdi:waypoint>
<omgdi:waypoint x="147.0" y="300.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">
<omgdi:waypoint x="147.0" y="355.0"></omgdi:waypoint>
<omgdi:waypoint x="147.0" y="420.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>


三、java实例化流程

当配置文件写好、流程图绘制完毕后,就可以直接上代码进行测试了:

ActivitiDemo.java

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.apache.commons.io.*;
import org.junit.Test;

public class ActivitiDemo {

ProcessEngine pe=ProcessEngines.getDefaultProcessEngine();
/**部署流程定义*/
@Test
public void deploymentProcessDefinition(){
Deployment deploye=pe.getRepositoryService()//与流程定义和部署对象的Service
.createDeployment()//创建一个部署对象
.name("部署名称")
.addClasspathResource("diagrams/MyProcess.bpmn")//从classpath加载,一次只能加载一个文件
.addClasspathResource("diagrams/MyProcess.png")
.deploy();
System.out.println(deploye.getId());
System.out.println(deploye.getName());
}
}

这一个测试就是针对这个流程最开始的启动工作来做的。启动完毕后,会在数据库中得到24张表。目前在这个流程中,由于这个流程是单线操作,所以存在一个流程实例,一个流程对象。ProcessEngine是整个流程管理的核心,通过引擎来管理所有的流程操作,在这里,流程引擎通过ProcessEngines.getDefaultProcessEngine()方法获得;引擎中创建了各种操作流程的Service,包括:

ResponsitoryService:管理流程定义

RuntimeService:执行管理定义

TaskService:任务管理定义

HistoryService:历史管理定义

IdentityService:组织机构管理定义

FormService:任务表单管理定义

执行测试方法,可以将其打印出来,其中5001是流程ID,流程名称则是在创建流程时赋予的名称。这个部署完毕,就会在数据库中act_re_deployment(流程表)表中留下一条记录。

5001
部署名称




部署流程定义后,需要将其实例化,需要启动流程实例,测试代码为:

@Test
public void startProcessInstance(){
ProcessInstance processInstance=pe.getRuntimeService()//启动相关的Service
.startProcessInstanceByKey("helloworld");//通过流程Key启动,key对应的是bpmn文件中的ID属性
System.out.println("流程实例ID"+processInstance.getId());
System.out.println("流程定义ID"+processInstance.getProcessDefinitionId());
}

流程实例ID7501
流程定义IDhelloworld:3:5004

这样就获取了一个流程实例,在流程实例表中可以看到增加了一条数据,说明这个流程开始启动了:



四、办理人执行任务

流程实例启动后,我们的研究对象就从流程实例转到流程对象了,流程对象可以在act_ru_execution(流程对象表)中查看,可以在任务表中查询到相应的历史任务(act_hi_taskinst)和正在进行的任务(act_ru_task),可以看到流程的进展情况;可以看到任务流程在开始后已经变成了“提交申请”,转给了办理人 张三。

流程对象表:



任务表:



当然,这写查询的操作可以用java完成,我们在任务表中看到当前有一个任务记录,办理人Assignee是张三,这个是在bpmn表中定义好了的。可以用java语句来审批一下任务,让工作流继续传递下去,下面就是查询个人任务并完成个人任务的写法;

/**查询当前人的个人任务*/
@Test
public void findProcessTask(){
List<Task> t=pe.getTaskService()
.createTaskQuery()
.taskAssignee("张三")
.list();
if(t!=null&&t.size()>0){
for(Task task:t){
System.out.println("任务ID"+task.getId());
System.out.println("任务名称"+task.getName());
System.out.println(task.getCreateTime());
System.out.println("办理人"+task.getAssignee());//办理人
System.out.println("流程实例ID"+task.getProcessInstanceId());//流程实例ID
System.out.println("执行对象ID"+task.getExecutionId());//流程实例ID
System.out.println("流程定义ID"+task.getProcessDefinitionId());//流程实例ID
}
}
}

任务ID7504
任务名称提交申请
Tue Jan 30 16:19:43 CST 2018
办理人张三
流程实例ID7501
执行对象ID7501
流程定义IDhelloworld:3:5004

可以将此任务的状态设置为完成,在java中的测试代码为

/**完成任务*/
@Test
public void completeTask(){
pe.getTaskService()
.complete("7504");
}

这是如果打开任务表,就会发现任务已经由张三转为李四了,表明张三的提交审批任务已经完成,当前的任务会转给李四,可以在ru_task表中证实;



同理,获取当前任务的ID后,完成任务,就会讲此任务转给王五,依此类推,直至流程结束。

完成流程后,可以在hi_taskinst表(历史任务表)中查看到完成的任务记录



也可以在hi_procinst(历史流程表)中看到流程记录,可以看到这是一个有始有终的项目,包含有start_time,end_time;



五、附

这是一个Activiti的逻辑说明例子,在实际项目中,任务办理人不会直接写死在bpmn中,各种任务的ID,办理人等也会由程序获取,并且关联在一起。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: