Java Activiti是一个开源的工作流引擎,用于管理和执行业务流程。
它是基于BPMN 2.0标准的,提供了丰富的功能和灵活性。
Java Activiti的工作原理如下:
1.Java Activiti 流程建模
使用BPMN 2.0标准的图形化编辑器,可以创建和定义业务流程模型。这些模型描述了流程中的各个任务、活动、网关、事件等。
使用工具:
InteliJ IDEA 插件:Activiti BPMN visualizer
使用方法参考:https://blog.csdn.net/qq_51726114/article/details/124363712
插件安装后,新建文件,画流程图:
注意上面的四个参数,后面会用于定位这个节点。
2. Java Activiti 流程部署
将流程模型部署到Activiti引擎中,引擎会解析和存储流程定义相关的信息,包括流程图、任务分配、表单等。
流程部署核心代码:
@Autowired
private ProcessEngine processEngine;
public static final String processDefinitionKey = "fbr_1";
public static final String resourceFilePath = "/process/fbr_1.bpmn20.xml";
public static final String resourceName = "fbr_1.bpmn20.xml";
@GetMapping("/deploy")
public ApiResult create() {
InputStream inputStream = ResourceFileUtils.loadFile(resourceFilePath);
// 获取流程定义和部署对象相关的Service
RepositoryService repositoryService = processEngine.getRepositoryService();
// 创建部署对象
Deployment deployment = repositoryService
.createDeployment()
.name("Build FBR Request Process")// 声明流程的名称
.addInputStream(resourceName, inputStream)// 加载资源文件,一次只能加载一个文件
.deploy();// 完成部署
//4.输出部署的一些信息
System.out.println(deployment.getId());
System.out.println(deployment.getName());
return ApiResult.ok();
}
部署后,会在三张元数据表中写入数据:
-- 部署信息
-- id关联 下面两张表
select * from ACT_RE_DEPLOYMENT where name_ ='Build FBR Request Process' order by deploy_time_ desc;
-- 流程元数据:含流程图等字段
-- deploy_id_ 关联
select * from ACT_GE_BYTEARRAY where name_ ='fbr_1.bpmn20.xml';
-- 流程定义数据
-- deploy_id_ 关联
select * from ACT_RE_PROCDEF where key_ ='fbr_1';
这三张表的元数据,会始终保存,不同于下面会讲到的四张表实例数据表,流程最终完成后,所有实例数据会清除掉。
3. Java Activiti 流程实例化(启动流程)
通过Activiti引擎,可以根据已部署的流程定义创建流程实例。每个流程实例代表了一个具体的业务流程执行过程。
启动流程时,流程会处于第一个结点(开始结点后的第一个结点),想要获取节点信息,需要通过该节点配置的属性进行查询;
启动流程核心代码:
@GetMapping("/start")
public ApiResult start(@RequestParam("assingee") String assingee) {
TaskService taskService = processEngine.getTaskService();
RuntimeService runtimeService = processEngine.getRuntimeService();
Map<String, Object> param = new HashMap<>();
param.put("submitter", assingee);// 流程必须要有发起人,否则会报错提示;
// 一般同流程文件名称
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey, param);
//4.输出实例的相关信息
System.out.println("流程部署id:" + processInstance.getDeploymentId());//null
System.out.println("流程定义id:" + processInstance.getProcessDefinitionId());//fbr_1:2:5f8494b9-7a0a-11ee-b0d9-4e796eddc638
System.out.println("流程实例id:" + processInstance.getId());//e464157a-7a0a-11ee-b0d9-4e796eddc638
System.out.println("流程活动id:" + processInstance.getActivityId());//null
return ApiResult.ok();
}
流程启动后,会在四张数据表中写入第一个结点的数据:
-- 流程任务表,
-- ACT_RU_TASK.proc_def_id=ACT_RE_PROCDEF.id
-- proc_inst_id 根节点 实列 id,结点变换也会一直不变,只会改变 name等字段
select * from ACT_RU_TASK where proc_def_id_ ='fbr_1:2:5f8494b9-7a0a-11ee-b0d9-4e796eddc638' order by create_time_ desc;
-- 实例表,是一个维表,
select * from ACT_RU_EXECUTION
where proc_def_id_ ='fbr_1:2:5f8494b9-7a0a-11ee-b0d9-4e796eddc638'
and root_proc_inst_id_ ='e464157a-7a0a-11ee-b0d9-4e796eddc638'
order by start_time_ desc;
-- user表
-- 同 ACT_RU_IDENTITYLINK.TASK_ID_=ACT_RU_EXECUTION.id 关联
select * from ACT_RU_IDENTITYLINK
where 1=1
and (proc_inst_id_ ='e464157a-7a0a-11ee-b0d9-4e796eddc638'
or task_id_ ='e480c53d-7a0a-11ee-b0d9-4e796eddc638'
)
-- 运行时变量;
-- 同流程任务表 ACT_RU_TASK.proc_inst_id 关联,
select * from ACT_RU_VARIABLE
where proc_inst_id_ ='e464157a-7a0a-11ee-b0d9-4e796eddc638'
4. Java Activiti 任务分配(获取结点任务)
根据流程定义中定义的任务分配规则,Activiti引擎会将任务分配给相应的参与者或角色。参与者可以是用户、组织或其他参与者。
核心代码:
@GetMapping("/getTaskList")
public void getTaskList(@RequestParam("assignee") String assignee) {
//1.得到ProcessEngine对象
//2.得到TaskService对象
TaskService taskService = processEngine.getTaskService();
//3.根据流程定义的key,负责人assignee来实现当前用户的任务列表查询
//获取任务集合 (ACT_RU_TASK 数据,task.getId等所有数据皆属于该表字段)
List<Task> taskList = taskService.createTaskQuery()
.processDefinitionKey(processDefinitionKey)// 指定流程id
.processDefinitionName("fbr_1")// 指定流程名称
.taskCandidateUser(assignee)// 指定接收人
.taskName("提交请假申请")// 指定结点name
.list();
for (Task task : taskList) {
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());
System.out.println("执行对象ID:" + task.getExecutionId());
System.out.println("流程定义ID:" + task.getProcessDefinitionId());
System.out.println("#########################################################");
}
}
assignee 只代表一种参数,taskCandidateUser也只代表一种查询方式,
具体需要根据流程图的配置字段来。
核心 SQL 语句:
select
distinct RES.*
from
ACT_RU_TASK RES
inner join ACT_RU_IDENTITYLINK I on
I.TASK_ID_ = RES.ID_
inner join ACT_RE_PROCDEF D on
RES.PROC_DEF_ID_ = D.ID_
where
RES.NAME_ = '提交请假申请'
and D.KEY_ = 'fbr_1'
and D.NAME_ = 'fbr_1'
and RES.ASSIGNEE_ is null
and I.TYPE_ = 'candidate'
and ( I.USER_ID_ = 'leiming5'
or I.GROUP_ID_ in ('activitiTeam') )
order by
RES.ID_ asc
5. 任务执行(让任务动起来)
参与者可以通过Activiti引擎完成分配给他们的任务。任务可以包括用户任务、服务任务、脚本任务等。
执行任务就是完成当前结点的任务,流程进入下一个节点,
这里需要将下个节点的数据(也可以是数据id,不存放具体数据)和审批人传入;使得下个节点的审批人能收到
核心代码:
@GetMapping("/complete")
public ApiResult complete(@RequestParam("assignee") String assignee) {
TaskService taskService = processEngine.getTaskService();
List<Task> taskList = taskService.createTaskQuery()
.processDefinitionKey(processDefinitionKey)// 指定流程id
.processDefinitionName("fbr_1")// 指定流程名称
.taskCandidateUser(assignee)// 指定接收人
.taskName("提交请假申请")// 指定结点name
.list();
//4.处理任务,结合当前用户任务列表的查询操作的话,任务ID:task.getId()
for (Task task : taskList) {
Map<String, Object> param = new HashMap<>();
param.put("person_1", "a,b");// 将下个节点的 审批人传入;使得下个节点的审批人能收到;
param.put("person_2", "c,d");
taskService.complete(task.getId(), param);
//5.输出任务的id
System.out.println(task.getId());
}
return ApiResult.ok();
}
核心 sql :
更新第三步中的四张表:删除当前结点的数据,新增下一个结点的数据。
ACT_RU_TASK.proc_inst_id 不会变,只会改变结点的其他属性。
6. 流程控制
在流程执行期间,Activiti引擎会根据流程定义中定义的条件和网关,控制流程的走向和执行顺序。这包括并行网关、排他网关、事件网关等。
7. 监控和管理
Activiti引擎提供了监控和管理工具,可以跟踪和管理流程实例的执行情况,包括任务状态、流程进度、异常处理等。