public class StartActiviti {
public static void main(String[] args) {
//第一步:部署activiti环境(25张表)
//一般的activiti部署:
//先通过配置文件得到引擎配置对象,通过这个配置对象build得到processEngine
//(在创建ProcessEngine 时会自动创建25张表,这样就有了activiti的环境。)
//然后通过processEngine得到各种Service接口
//接下来是简单部署的方式
//(要求 activiti.cfg.xml 文件名及路径固定,且 activiti.cfg.xml 文件中有 processEngineConfiguration 的配置)
//使用classpath下的activiti.cfg.xml中的配置创建processEngine
ProcessEngine processEngine =
ProcessEngines.getDefaultProcessEngine();
System.out.println(processEngine);
//第二步:流程定义(画流程图)
//在类路径下新建一个文件夹diagram,里面new -> Activiti Diagram
//第三步,流程定义部署(结果: 流程定义信息增加到activiti到相关表中)
//3.1 通过processEngine得到repositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
//3.2通过repositoryService进行部署,得到Deployment对象
Deployment deployment = repositoryService.createDeployment()
.addClasspathResource("diagram/holiday.bpmn")
.addClasspathResource("diagram/holiday.png")
.name("请假流程第一次部署")
.deploy();
//3.3输出一些请假信息
System.out.println("部署ID:"+deployment.getId());
System.out.println("部署名称:"+deployment.getName());
/**
* 总结:
* 影响activiti的表有哪些?
* act_re_deployment 部署信息(部署时间,部署名称)
act_re_procdef 流程定义的一些信息(就是画流程图时的一些信息:name,唯一key(画流程图时的id,对应在数据库是key字段)等)
act_ge_bytearray 流程定义的bpmn文件及png文件
*/
//第四步,启动一个流程实例
//4.1 还是通过processEngine的getRuntimeService()得到runtimeService对象
RuntimeService runtimeService = processEngine.getRuntimeService();
//4.2 创建流程实例(要求知道流程定义的key才能创建)
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("holiday");
//4.3 输出流程实例相关信息
System.out.println("流程部署ID:"+processInstance.getDeploymentId());
System.out.println("流程定义ID:"+processInstance.getProcessDefinitionId());
System.out.println("流程实例ID:"+processInstance.getId());
System.out.println("活动ID:"+processInstance.getActivityId());
//第五步。查询某一个用户的任务列表
TaskService taskService = processEngine.getTaskService();
//5.1查询任务(根据流程定义的key,告诉activiti你要看哪一个流程。根据assignee,告诉activiti你要查哪一个人的任务)
List<Task> tasks = taskService.createTaskQuery()
.processDefinitionKey("holiday")
.taskAssignee("zhangsan")
.list();
//5.2打印任务信息
for (Task task : tasks) {
System.out.println("任务名称:" + task.getName());
System.out.println("任务id:" + task.getId());
System.out.println("任务负责人:" + task.getAssignee());
System.out.println("当前任务所在的流程实例ID:" + task.getProcessInstanceId());
System.out.println("当前任务的流程定义ID:" + task.getProcessDefinitionId() );
}
/**
* 第五步总结:
* 在act_hi_procinst看到流程实例ID
* 在act_hi_taskinst看到任务实例ID,任务负责人,任务名称
*/
}
}
分割线
流程定义的查询:
public class QueryProcessDefinition {
public static void main(String[] args) {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
//再由repositoryService获得processDefinitionQuery,相当于一个查询器
ProcessDefinitionQuery processDefinitionQuery =
repositoryService.createProcessDefinitionQuery();
//通过查询器,根据流程定义key进行查询。(每一套流程都会有一个唯一的key,也就是画bpmn时的id)
//orderByProcessDefinitionVersion这里是根据流程定义版本号排序
List<ProcessDefinition> processDefinitions = processDefinitionQuery
.processDefinitionKey("holiday")
.orderByProcessDefinitionVersion()
.desc()
.list();
for (ProcessDefinition processDefinition : processDefinitions) {
System.out.println("=============================");
System.out.println("流程定义id:" + processDefinition.getId());
System.out.println("流程定义版本:" + processDefinition.getVersion());
System.out.println("流程定义key:" + processDefinition.getKey());
}
}
}
注:经过测试,如果一套流程有多个版本,并且是分开部署的,以后再启动流程实例时以最新版的流程定义创建流程实例,下面结果是定义了第二版请假流程后的定义查询结果:
=============================
流程定义id:holiday:2:10004
流程定义版本:2
流程定义key:holiday
流程部署id:10001
=============================
流程定义id:holiday:1:4
流程定义版本:1
流程定义key:holiday
流程部署id:1
附上
版本1的流程定义bpmn:
版本2的流程定义bpmn:
删除流程定义(根据流程部署id删除)
//根据部署id删除一个流程(这里删除的是版本2,所以需要传的是部署请假版本2时的id)
repositoryService.deleteDeployment("10001");
/**
* 影响的表有:
* act_ge_bytearray : 存着流程资源信息(bpmn,png)
* act_re_deployment : 存着流程部署信息 (虽然一次部署可以部署多个流程定义,但建议还是一次部署一个流程)
* act_re_procdef : 存放着流程定义信息
*
* 大体上与部署流程定义时影响的表一直
*
* 如果删掉的流程定义有正在运行的流程实例(未走完的流程),但仍要删除,只能通过
* repositoryService.deleteDeployment("10001",true);
* 进行级联删除
*/
需求:
- 1.从Activiti的act_ge_bytearray表中读取两个资源文件
- 2.将两个资源文件保存到路径:D:\java\files
思路:
repositoryService —> processDefinition ----> deployentId
public class QueryBpmnAndPng {
public static void main(String[] args) throws IOException {
//1.得到ProcessEngine对象
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.得到RepositoryService对象
RepositoryService repositoryService = processEngine.getRepositoryService();
//3.得到查询器:ProcessDefinitionQuery对象
//4.设置查询条件
//5.执行查询操作,查询出想要的流程定义
// 其中3,4,5步可以连着一块写
ProcessDefinition processDefinition = repositoryService
.createProcessDefinitionQuery()
.processDefinitionKey("holiday")
.singleResult();
//6.通过流程定义信息,得到部署ID
String deploymentId = processDefinition.getDeploymentId();
//7.通过repositoryService的方法,实现读取图片信息及bpmn文件信息(输入流)
//getResourceAsStream()方法的参数说明:第一个参数部署id,第二个参数代表资源名称
//processDefinition.getDiagramResourceName() 代表获取png图片资源的名称
//processDefinition.getResourceName()代表获取bpmn文件的名称
InputStream pngIs = repositoryService
.getResourceAsStream(deploymentId,processDefinition.getDiagramResourceName());
InputStream bpmnIs = repositoryService
.getResourceAsStream(deploymentId,processDefinition.getResourceName());
//8.构建出OutputStream流
OutputStream pngOs =
new FileOutputStream("E:\\activiti\\bpmn&png\\"+processDefinition.getDiagramResourceName());
OutputStream bpmnOs =
new FileOutputStream("E:\\activiti\\bpmn&png\\"+processDefinition.getResourceName());
//9.输入流,输出流的转换 commons-io-xx.jar中的方法
IOUtils.copy(pngIs,pngOs);
IOUtils.copy(bpmnIs,bpmnOs);
//10.关闭流
pngOs.close();
bpmnOs.close();
pngIs.close();
bpmnIs.close();
}
}
查阅流程历史相关信息:
即使流程定义信息删除了,但这个流程执行过的任务activity仍保存在数据库中。
可以通过HistoryService接口查询:(通过流程定义ID查询)
一样的套路:
(前提要求知道流程定义ID)
processEngine —> historyService —> historicActivityInstanceQuery —>
List
public class QueryHistoryActivity {
public static void main(String[] args) {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
HistoryService historyService = processEngine.getHistoryService();
List<HistoricActivityInstance> historicActivityInstances = historyService
.createHistoricActivityInstanceQuery()
.processInstanceId("12501")
.list();
for (HistoricActivityInstance historicActivityInstance : historicActivityInstances) {
System.out.println("这个历史活动:" + historicActivityInstance.getActivityName());
System.out.println("这个历史活动id:"+ historicActivityInstance.getActivityId());
System.out.println("这个历史流程活动参与人:"+historicActivityInstance.getAssignee());
System.out.println("这个历史活动的流程实例Id:" + historicActivityInstance.getProcessInstanceId());
System.out.println("这个历史活动的流程定义Id:" + historicActivityInstance.getProcessDefinitionId());
System.out.println("----------------------------------------------------------");
}
}
}
结果:
这个历史活动:Start
这个历史活动id:startevent1
这个历史流程活动参与人:null
这个历史活动的流程实例Id:12501
这个历史活动的流程定义Id:holiday:2:10004
----------------------------------------------------------
这个历史活动:填写请假单
这个历史活动id:usertask1
这个历史流程活动参与人:zhangsan
这个历史活动的流程实例Id:12501
这个历史活动的流程定义Id:holiday:2:10004
----------------------------------------------------------
这个历史活动:部门领导审批
这个历史活动id:usertask2
这个历史流程活动参与人:lisi
这个历史活动的流程实例Id:12501
这个历史活动的流程定义Id:holiday:2:10004
----------------------------------------------------------
这个历史活动:End
这个历史活动id:endevent1
这个历史流程活动参与人:null
这个历史活动的流程实例Id:12501
这个历史活动的流程定义Id:holiday:2:10004
----------------------------------------------------------
这里12501是已经删掉的流程定义的流程实例id
第二天回来补彩蛋了:
当一个参与者查询他的代办任务list时,如果没有,返回 [] ,不是null
嗯…我还是太菜了