Activiti快速使用
使用步骤:
- 整合activiti
- 实现业务流程建模,使用BPMN实现业务流程图
- 部署业务流程到activiti
- 启动流程实例
- 查询待办事务
- 处理待办任务
- 结束流程
生命周期
静态阶段 : 包含流程设计和流程部署 —xml模型
运行时阶段: 用户发起流程,各责任人对流程进行审核驳回等操作,Activiti 自动的根据流程状态
历史阶段:对于以关闭或审核通过的历史流程,进行查询的管理
Activiti内置数据库的作用:
流程部署:将绘制好的流程上传到引擎
流程定义:部署之后,流程定义对象
流程实例:用户发起流程
流程任务:流程实例中每个节点的处理任务
服务架构:
activiti 的引擎配置文件,包括: ProcessEngineConfiguration 的定义、数据源定义、事务管理器等,
此文件其实就是一个 spring 配置文件
ProcessEngineConfiguration
两种配置方式:
一:Standalone,通常在 activiti.cfg.xml 配置文件中定义一个 id 为 processEngineConfiguration 的 bean,这里会使用 spring 的依赖注入来构建引擎。
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfig
uration">
<!-- 数据源 -->
<property name="dataSource" ref="dataSource" />
<!-- 数据库策略 -->
<property name="databaseSchemaUpdate" value="true"/>
</bean>
二:与spring整合配置文件
<!-- 工作流引擎配置bean -->
<bean id="processEngineConfiguration"
class="org.activiti.spring.SpringProcessEngineConfiguration">
<!-- 数据源 -->
<property name="dataSource" ref="dataSource" />
<!-- 使用spring事务管理器 -->
<property name="transactionManager" ref="transactionManager" />
<!-- 数据库策略 -->
<property name="databaseSchemaUpdate" value="drop-create" />
<!-- activiti的定时任务关闭 -->
<property name="jobExecutorActivate" value="false" />
</bean>
<!-- 流程引擎 -->
<bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
<property name="processEngineConfiguration"
ref="processEngineConfiguration" />
</bean>
<!-- 资源服务service -->
<bean id="repositoryService" factory-bean="processEngine"
factory-method="getRepositoryService" />
<!-- 流程运行service -->
<bean id="runtimeService" factory-bean="processEngine"
factory-method="getRuntimeService" />
<!-- 任务管理service -->
<bean id="taskService" factory-bean="processEngine"
factory-method="getTaskService" />
<!-- 历史管理service -->
<bean id="historyService" factory-bean="processEngine"
factory-method="getHistoryService" />
<!-- 用户管理service -->
<bean id="identityService" factory-bean="processEngine"
factory-method="getIdentityService" />
<!-- 引擎管理service -->
<bean id="managementService" factory-bean="processEngine"
factory-method="getManagementService" />
创建ProcessEngineConfiguration对象:
//要求 activiti.cfg.xml 中必须有一个 processEngineConfiguration 的 bean
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml")
//也可以使用下边的方法,更改 bean 的名字
ProcessEngineConfiguration.createProcessEngineConfigurationFromResource(String resource, String beanName);
ProcessEngine创建
//通过ProcessEngineConfiguration创建ProcessEngine
ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine();
//使用classpath下的activiti.cfg.xml中的配置创建processEngine (activiti.cfg.xml 文件名及路径固定,且 activiti.cfg.xml 文件中有 processEngineConfiguration 的配置)
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
Service
Service | 描述 |
---|---|
RepositoryService | activiti 的资源管理类,部署查询流程定义,暂停激活,获取多种资源 |
RuntimeService | activiti 的流程运行管理类 |
TaskService | activiti 的任务管理类 |
HistoryService | activiti 的历史管理类 |
ManagerService | activiti 的引擎管理类 |
使用processEngine.getXXXService() 创建 |
流程定义与实例
部署
- 流程定义的部署
- activiti表有哪些?
- act_re_deployment 部署信息
- act_re_procdef 流程定义的一些信息,该表中KEY作为唯一识别
- act_ge_bytearray 流程定义的bpmn文件及png文件
一次部署一个流程,这样部署表和流程定义表是一对一有关系,方便读取流程部署及流程定义信息。
单个文件方式
//1.创建ProcessEngine对象
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.得到RepositoryService实例
RepositoryService repositoryService = processEngine.getRepositoryService();
//3.进行部署
Deployment deployment = repositoryService.createDeployment()
.addClasspathResource("diagram/holiday2.bpmn20.xml") //添加bpmn资源
.addClasspathResource("diagram/holiday2.bpmn20.png")
.name("请假申请单流程")
.deploy();
以上传文件方式部署
public void deployProcess(MultipartFile file, String companyId) throws IOException {
//1.获取上传的文件名
String fileName = file.getOriginalFilename();
//2.通过repositoryService进行流程部署
//DeploymentBuilder deploymentBuilder = repositoryService.createDeployment();
//文件名称,文件的bytes数组
//deploymentBuilder.addBytes(fileName,file.getBytes()); //部署流程
//deploymentBuilder.tenantId(companyId);//不同系统用一个流程定义来启动流程实例,tenantId用以区分同一个流程定义下分属不同系统的流程实例
DeploymentBuilder deploymentBuilder = repositoryService.createDeployment().addBytes(fileName, file.getBytes()).tenantId(companyId);
Deployment deploy = deploymentBuilder.deploy();
//3.打印部署结果
System.out.println(deploy);
}
压缩包方式
//1.创建ProcessEngine对象
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.得到RepositoryService实例
RepositoryService repositoryService = processEngine.getRepositoryService();
//3.转化出ZipInputStream流对象
InputStream is = ActivitiDeployment.class.getClassLoader().getResourceAsStream("diagram/holidayBPMN.zip");
//将 inputstream流转化为ZipInputStream流
ZipInputStream zipInputStream = new ZipInputStream(is);
//3.进行部署
Deployment deployment = repositoryService.createDeployment()
.addZipInputStream(zipInputStream) .name("请假申请单流程")
.deploy();//部署
Deployment
@Internal
public interface Deployment {
String getId();
String getName();
Date getDeploymentTime();
String getCategory();
String getKey();
String getTenantId();
}
启动流程实例
背后影响的表:
- act_hi_actinst 已完成的活动信息
act_hi_identitylink 参与者信息
act_hi_procinst 流程实例
act_hi_taskinst 任务实例
act_ru_execution 执行表
act_ru_identitylink 参与者信息
act_ru_task 任务
//1.得到ProcessEngine对象
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.得到RunService对象
RuntimeService runtimeService = processEngine.getRuntimeService();
//3.创建流程实例 流程定义的key需要知道 processDefinitionKey
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey);
查询processDefinition
// 流程定义key
String processDefinitionKey = "holiday";
// 获取repositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
// 查询流程定义
ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
//遍历查询结果
List<ProcessDefinition> list = processDefinitionQuery
.processDefinitionKey(processDefinitionKey)
.orderByProcessDefinitionVersion().desc().list();
//通过tenantId查询
List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery().processDefinitionTenantId(companyId)
.latestVersion().list();
ProcessDefinition
@Internal
public interface ProcessDefinition {
String getId();
String getCategory();
String getName();
String getKey();
String getDescription();
int getVersion();
String getResourceName();
String getDeploymentId();
String getDiagramResourceName();
boolean hasStartFormKey();
boolean hasGraphicalNotation();
boolean isSuspended();
String getTenantId();
String getEngineVersion();
}
查询ProcessInstance
流程在运行过程中可以查询流程实例的状态,当前运行结点等信息
//1.得到ProcessEngine对象
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.获取RuntimeService
RuntimeService runtimeService = processEngine.getRuntimeService();
// 流程定义key
String processDefinitionKey = "holiday";
//3.得到ProcessInstanceQuery对象,可以认为它就是一个查询器
//4.设置条件,并查询出当前的所有流程定义 查询条件:流程定义的key=holiday
//orderByProcessDefinitionVersion() 设置排序方式,根据流程定义的版本号进行排序 ProcessInstance中没有version
List<ProcessInstance> list = runtimeService
.createProcessInstanceQuery()
.processDefinitionKey(processDefinitionKey)//
.list();
//5.输出流程定义信息
for(ProcessInstance processInstance :list){
System.out.println("----------------------------");
System.out.println("流程实例id: " + processInstance.getProcessInstanceId());
System.out.println("所属流程定义id: " + processInstance.getProcessDefinitionId());
System.out.println("是否执行完成: " + processInstance.isEnded());
System.out.println("是否暂停: " + processInstance.isSuspended());
System.out.println(" 当 前 活 动 标 识 : " +
processInstance.getActivityId());
根据自己的业务id查询流程实例如自定义proc_instance表中的processId
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceBusinessKey( String processInstanceBusinessKey).singleResult();
激活与挂起
全部流程实例RepositoryService
//1.得到ProcessEngine对象
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.得到RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
//3.查询流程定义的对象,可以根据id或key查询,但此时id需要去表中查看
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
.processDefinitionKey("holiday").singleResult();
//或根据processKey和tenantId查询
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionKey(processKey)
.processDefinitionTenantId(companyId).latestVersion().singleResult();
//4.得到当前流程定义的实例是否都为暂停状态
boolean suspended = processDefinition.isSuspended();
String processDefinitionId = processDefinition.getId();
//5.判断
if(suspended){
//说明是暂停,就可以激活操作,可以根据id或key,此时id已可以查出
repositoryService.activateProcessDefinitionById(processDefinitionId,true
,null);
System.out.println("流程定义:"+processDefinitionId+"激活");
}else{
repositoryService.suspendProcessDefinitionById(processDefinitionId,true,null);
System.out.println("流程定义:"+processDefinitionId+"挂起");
}
单个流程实例
//1.得到ProcessEngine对象
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.得到RuntimeService
RuntimeService runtimeService = processEngine.getRuntimeService();
//3.查询流程实例对象 .processEngineInstanceBusinessKey("holiday")报错
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
.processInstanceId("2501").singleResult();
//4.得到当前流程定义的实例是否都为暂停状态
boolean suspended = processInstance.isSuspended();
String processInstanceId = processInstance.getId();
//5.判断
if(suspended){
//说明是暂停,就可以激活操作
runtimeService.activateProcessInstanceById(processInstanceId); System.out.println("流程:"+processInstanceId+"激活");
}else