工作流的主要步骤:流程定义--》部署流程--》开始流程--》查询流程信息--》结束流程
一,流程定义
流程定义就是根解析.bpmn后得到的流程定义规则的信息
二,部署流程
1.1部署流程的几种方式
①通过classpath部署
@Test
public void deployementProcessDefinition(){
Deployment deployment = processEngine.getRepositoryService()//获取流程定义和部署对象相关的Service
.createDeployment()//创建部署对象
.name("helloworld演示")//声明流程的名称
.addClasspathResource("diagrams/helloworld.bpmn")//加载资源文件,一次只能加载一个文件
.addClasspathResource("diagrams/helloworld.png")//
.deploy();//完成部署
System.out.println("部署ID:"+deployment.getId());
System.out.println("部署时间:"+deployment.getDeploymentTime());
}
②通过inputStream方式部署
@Test
public void deployementProcessDefinitionByInputStream() throws FileNotFoundException{
//获取资源相对路径
String bpmnPath = "diagrams/helloworld.bpmn";
String pngPath = "diagrams/helloworld.png";
//读取资源作为一个输入流
FileInputStream bpmnfileInputStream = new FileInputStream(bpmnPath);
FileInputStream pngfileInputStream = new FileInputStream(pngPath);
Deployment deployment = processEngine.getRepositoryService()//获取流程定义和部署对象相关的Service
.createDeployment()//创建部署对象
.addInputStream("helloworld.bpmn",bpmnfileInputStream)
.addInputStream("helloworld.png", pngfileInputStream)
.deploy();//完成部署
System.out.println("部署ID:"+deployment.getId());//1
System.out.println("部署时间:"+deployment.getDeploymentTime());
}
③通过zip文件
此方式要把bpmn文件和png文件同时压缩到一个zip包中,然后通过inputStream导入
@Test
public void deployementProcessDefinitionByzip(){
//从classpath路径下读取资源文件
InputStream in = this.getClass().getClassLoader().getResourceAsStream("diagrams/helloworld.zip");
ZipInputStream zipInputStream = new ZipInputStream(in);
Deployment deployment = processEngine.getRepositoryService()//获取流程定义和部署对象相关的Service
.createDeployment()//创建部署对象
.addZipInputStream(zipInputStream)//使用zip方式部署,将helloworld.bpmn和helloworld.png压缩成zip格式的文件
.deploy();//完成部署
System.out.println("部署ID:"+deployment.getId());
System.out.println("部署时间:"+deployment.getDeploymentTime());
}
三,开始流程
/**
* 启动流程
* RuntimeService
*/
@Test
public void startProcess() {
RuntimeService runtimeService = processEngine.getRuntimeService();
//可根据id、key、message启动流程
runtimeService.startProcessInstanceByKey("myProcess_1");
}
四,查询流程
/**
* 查看任务
* TaskService
*/
@Test
public void queryTask() {
TaskService taskService = processEngine.getTaskService();
//根据assignee(代理人)查询任务
String assignee = "emp";
List<Task> tasks = taskService.createTaskQuery().taskAssignee(assignee).list();
int size = tasks.size();
for (int i = 0; i < size; i++) {
Task task = tasks.get(i);
}
for (Task task : tasks) {
System.out.println("taskId:" + task.getId() +
",taskName:" + task.getName() +
",assignee:" + task.getAssignee() +
",createTime:" + task.getCreateTime());
}
}
五,办理任务
/**
* 办理任务
*/
@Test
public void handleTask() {
TaskService taskService = processEngine.getTaskService();
//根据上一步生成的taskId执行任务
String taskId = "5004";
taskService.complete(taskId);
}
六,流程的CRUD
①增加(发布流程,部署流程)
@Test
public void deploymentrocessDefinition_classpath(){
Deployment deployment = processEngine.getRepositoryService()//获取流程定义和部署对象相关的Service
.createDeployment()//创建部署对象
.name("定义流程")//声明流程的名称
.addClasspathResource("leave.bpmn")//加载资源文件,一次只能加载一个文件
.deploy();//完成部署
System.out.println("部署ID:"+deployment.getId());//1
System.out.println("部署时间:"+deployment.getDeploymentTime());
}
②查询流程信息
/*
查询流程信息
*/
@Test
public void findProcessDefinition(){
List<ProcessDefinition> list = processEngine.getRepositoryService()
.createProcessDefinitionQuery()
//.deploymentId()根据部署对象ID查询
//.processDefinitionId()使用流程定义ID查询
//.processDefinitionKey()使用流程定义key查询
//.processDefinitionNameLike()使用流程定义的名称模糊查询
/* 排序*/
.orderByProcessDefinitionVersion().asc()//按照版本升序排列
//.orderByProcessDefinitionName().desc()按照流程定义降序排列
//返回结果集
.list();//返回一个list集合,对应着key这种多返回值的查询
//.singleResult();返回一个结果集,对应id这种单一返回值的查询
//.count()返回结果数量
//.listPage(firt,max)分页查询
if(list != null && list.size() > 0){
for (ProcessDefinition p : list){
System.out.println(p.getId());
System.out.println(p.getName());
}
}
}
③删除流程
/*
删除流程
*/
@Test
public void deleteProcessDefinition(){
String deploymentId = "1";
/*
此方法只能删除没有启动的流程,如果流程启动则抛出异常
*/
//processEngine.getRepositoryService().deleteDeployment(deploymentId);
processEngine.getRepositoryService().deleteDeployment(deploymentId,true);//此方法可以删除已启动的流程,级联删除
}
④修改
注意,流程定义的信息不能被修改,只能通过新发布一个流程(key与要修改的流程的key一样),然后通过版本号把旧的流程替换掉。
/*
查询最新版本的流程定义
*/
@Test
public void findLastView(){
List<ProcessDefinition> list = processEngine.getRepositoryService()
.createProcessDefinitionQuery()
.orderByProcessDefinitionVersion().asc()
.list();
//map集合的特点:当map的key一样的时候,后一次的值将替换前一次的值
Map<String,ProcessDefinition> map = new LinkedHashMap<String, ProcessDefinition>();
if (list != null && list.size()>0){
for (ProcessDefinition pd : list){
map.put(pd.getKey(),pd);
}
}
List<ProcessDefinition> pdList = new ArrayList<ProcessDefinition>(map.values());
if (pdList != null && pdList.size() > 0){
for (ProcessDefinition pd : pdList){
System.out.println("流程定义id:" + pd.getId());
System.out.println("流程定义名称:" + pd.getName());
System.out.println("流程定义key:" + pd.getKey());
System.out.println("流程定义版本:" + pd.getVersion());
}
}
}
============部署流程======================================
三个主要的表:
act_re_deploment #部署对象表
每部署一次增加一套记录
act_re_proccdef #流程定义表
部署每个新的流程定义对象都在这个表增加一条记录
act_ge_bytearray #资源文件表
每部署一次增加两条记录,一条是bpmn规则文件,一条的图片的,以二进制形式存储。
act_ge_property #主键生成策略表
==============开启流程实例==================================
表面ru表示正在执行
act_ru_execution ,此表存储正在执行的流程
此表中,id是执行对象id,PROC_INST_ID是流程实例id
如果单例流程(即bpmn图中没有分支和聚合),上述两列的值是一样的
act_hi_procinst 此表存储那些开启过的流程实例
如果现在流程还在执行,则END_TIME列为null
如果现在流程已经完成,则END_TIME列为完成的时间
act_ru_task 正在执行的任务表
只有节点是userTask的时候,该表才会存在数据,而且是该UserTask的数据
act_hi_taskinst 任务历史表
只有节点是userTask的时候,该表才会存在数据
act_hi_actinst 所有已执行的节点表
=========================================================
注意:流程实例只有一个,执行对象有多个(bpmn图有分支的时候)
流程实例就表示一个流程从开始到结束,所以流程实例只有一个。
Activiti用Execution这个对象表示流程所执行的每一个节点,在没有并发的情况下,
Execution就是同ProcessInstance。
ProcessInstance继承Execution。