1.工作流介绍
工作流是一系列的规范流程,让业务按照拟定的规则处理和运转,本质上是一系列逻辑相关的活动的集合。如:员工请假–>部门审批–>公司领导审核–>人力资源部备案。activiti工作流引擎就是让任务能够按拟定的流程自动的驱动下去,不再需要我们实现流程的驱动,记录流程的流转情况等等,提供流程生命周期的管理功能。
activiti用户手册:http://www.mossle.com/docs/activiti/index.html#N10007
2.activiti数据库表结构
Activiti的后台是有数据库的支持,所有的表都以ACT_开头。 第二部分是表示表的用途的两个字母标识。 用途也和服务的API对应。
ACT_RE_: 'RE’表示repository。 这个前缀的表包含了流程定义和流程静态资源 (图片,规则,等等)。
ACT_RU_: 'RU’表示runtime。 这些运行时的表,包含流程实例,任务,变量,异步任务,等运行中的数据。 Activiti只在流程实例执行过程中保存这些数据, 在流程结束时就会删除这些记录。 这样运行时表可以一直很小速度很快。
ACT_ID_: 'ID’表示identity。 这些表包含身份信息,比如用户,组等等。
ACT_HI_: 'HI’表示history。 这些表包含历史数据,比如历史流程实例, 变量,任务等等。
ACT_GE_*: 通用数据, 用于不同场景下,如存放资源文件。
表结构操作:
资源库流程规则表
- act_re_deployment 部署信息表
- act_re_model 流程设计模型部署表
- act_re_procdef 流程定义数据表
运行时数据库表
- act_ru_execution 运行时流程执行实例表
- act_ru_identitylink 运行时流程人员表,主要存储任务节点与参与者的相关信息
- act_ru_task 运行时任务节点表
- act_ru_variable 运行时流程变量数据表
历史数据库表
- act_hi_actinst 历史节点表
- act_hi_attachment 历史附件表
- act_hi_comment 历史意见表
- act_hi_identitylink 历史流程人员表
- act_hi_detail 历史详情表,提供历史变量的查询
- act_hi_procinst 历史流程实例表
- act_hi_taskinst 历史任务实例表
- act_hi_varinst 历史变量表
组织机构表
- act_id_group 用户组信息表
- act_id_info 用户扩展信息表
- act_id_membership 用户与用户组对应信息表
- act_id_user 用户信息表
通用数据表
- act_ge_bytearray 二进制数据表
- act_ge_property 属性数据表存储整个流程引擎级别的数据,初始化表结构时,会默认插入三条记录,
3.activiti工作流引擎中核心类介绍
ProcessEngine是Activiti中最核心的类,其他的类都是由他而来。主要能够获取RepositoryService、RuntimeService、TaskService、HistoryService、IdentityService、FormService、ManagerService。
RepositoryService:是Activiti的仓库服务类。所谓的仓库指流程定义文档的两个文件:bpmn文件和流程图片。
RuntimeService:是activiti的流程执行服务类。可以从这个服务类中获取很多关于流程执行相关的信息。
TaskService:是activiti的任务服务类。可以从这个类中获取任务的信息。
HistoryService:是activiti的查询历史信息的类。在一个流程执行完成后,这个对象为我们提供查询历史信息。
4.springboot(1.5.21.RELEASE)与activiti(6.0.0)整合
4.1 导入依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter-basic</artifactId>
<version>6.0.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
2.编辑application.properties配置文件
spring.datasource.url=jdbc:mysql://localhost:3306/activity?characterEncoding=UTF-8
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.jpa.properties.hibernate.hbm2ddl.auto=update
#false不自部署bpmn,ture自动部署processes下的bpmn
spring.activiti.check-process-definitions=false
3.编辑activitiConfig配置文件
@Configuration
@ConfigurationProperties(prefix ="spring.datasource")//开启前缀扫描
public class ActivitiConfig {
@Autowired
ProcessEngine processEngine;
String driverClassName;
String url;
String username;
String password;
@Bean
public ProcessEngine processEngine() {
//获取config对象
ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration
.createStandaloneProcessEngineConfiguration();
//Jdbc相关设置
//String driverClassName = "com.mysql.jdbc.Driver";
processEngineConfiguration.setJdbcDriver(driverClassName);
//String url = "jdbc:mysql://localhost:3306/Activity?useUnicode=true&characterEncoding=utf-8";
processEngineConfiguration.setJdbcUrl(url);
//String username = "root";
processEngineConfiguration.setJdbcUsername(username);
//String password = "root";
processEngineConfiguration.setJdbcPassword(password);
//DB_SCHEMA_UPDATE_FALSE//不自动创建表,不存在表就抛出异常
//DB_SCHEMA_UPDATE_CREATE_DROP//每次运行都删除表,再创建新表
//DB_SCHEMA_UPDATE_TRUE//如果表不存在就创建,存在就直接使用表
//设置是否自动更新
processEngineConfiguration.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
//获取引擎对象(检查数据库连接环境等信息是否正确)
ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine();
return processEngine;
}
//RepositoryService:管理流程定义:bpmn文件和流程图片
@Bean
public RepositoryService repositoryService() {
return processEngine.getRepositoryService();
}
/**
*
* @return RuntimeService:执行管理,启动、推进、删除流程等操作
*/
@Bean
public RuntimeService runtimeService() {
return processEngine.getRuntimeService();
}
/**
*
* @return TaskService:任务管理
*/
@Bean
public TaskService taskService() {
return processEngine.getTaskService();
}
/**
*
* @return HistoryService:历史管理(执行完的数据管理)
*/
@Bean
public HistoryService historyService() {
return processEngine.getHistoryService();
}
}
//还需要用到其他对象是在这里面加配置
//解决中文乱码
@Configuration
public class MySpringProcessEngineConfiguration {
@Bean
public ProcessEngineConfiguration processEngineConfiguration (){
ProcessEngineConfiguration processEngineConfiguration = new SpringProcessEngineConfiguration();
processEngineConfiguration.setActivityFontName("宋体");
processEngineConfiguration.setLabelFontName("宋体");
return processEngineConfiguration;
}
}
4.创建.bpmn流程图
5.测试
@RunWith(SpringRunner.class)
@SpringBootTest
public class ShenPiTest {
@Autowired
ProcessEngine processEngine;
@Autowired
RepositoryService repositoryService;
@Autowired
RuntimeService runtimeService;
@Autowired
TaskService taskService;
@Autowired
HistoryService historyService;
//1.发布流程
@Test
public void deploy() {
//获取仓库服务实例
Deployment deployment = repositoryService.createDeployment()
.name("审批流程(流程变量)")//添加部署规则的显示别名
.addClasspathResource("processes/shenpi.bpmn")
.addClasspathResource("processes/shenpi.png")
.deploy();//完成发布
System.out.println(deployment.getId()+"****************"+deployment.getName());
}
//2.启动流程实例,当流程达到一个节点时会在act_ru_execution表中产生一条数据
//如果是用户任务节点,还会在act_ru_task表中产生一条数据(任务的办理人,任务的创建时间)
@Test
public void startProcess(){
//按照流程定义id启动
//runtimeService.startProcessInstanceById(dp.getId());
//通过流程定义的key启动,会启动最高版本
String processDefinitionKey = "myShenpi";
ProcessInstance pi = runtimeService.startProcessInstanceByKey(processDefinitionKey);
System.out.println("pid:"+pi.getId()+",activitiId:"+pi.getActivityId()
+",pdId:"+pi.getProcessDefinitionId());
}
//3.设置流程变量
@Test
public void setVariables(){
//获取执行的service,指定办理人
String assigneeUser = "张三";
//流程实例id
String processInstanceId = "47501";
Task task = taskService.createTaskQuery()//创建任务查询
//.taskAssignee(assigneeUser)//指定办理人
.processInstanceId(processInstanceId)//指定流程实例id
.singleResult();
System.out.println(task.getId());
/**
* 变量中存放基本数据类型
*/
taskService.setVariable(task.getId(),"请假人","张三1");//使用流程变量的 名称和流程变量的值设置流程变量,一次只能设置一个值
taskService.setVariableLocal(task.getId(),"qingjiatianshu",6);
taskService.setVariable(task.getId(),"qingjiarenqi",new Date());
/**
* 变量中存放javabean对象,存放的对象需要实现序列化
*/
}
//4.获取流程变量
@Test
public void getVariables(){
Task task = taskService.createTaskQuery()
.processInstanceId("47501")
.singleResult();
System.out.println((String)taskService.getVariable(task.getId(), "请假人"));
}
//3.查看个人任务(待办)
@Test
public void queryPersonalTask() throws Exception{
//指定任务办理者
String assignee = "zhangsan";
//查询任务列表
List<Task> list = taskService.createTaskQuery()//创建任务查询对象
//.taskAssignee(assignee)//指定个人任务办理人
.list();
//遍历插看内容
for (Task task:list
) {
System.out.println("taskId:"+task.getId()+"taskName:"+task.getName());//taskId:17505taskName:UserTask1
System.out.println("***************************");
}
}
//4.办理任务
@Test
public void completeTask(){
String taskId = "17505";
//执行任务
taskService.complete(taskId);
System.out.println("完成任务!");
}
//5.查询流程状态(判断流程实在执行还是已经结束)
@Test
public void queryProcessState(){
String processInstanceId = "17501";
ProcessInstance pi = runtimeService.createProcessInstanceQuery()//创建流程实例查询,查询正在执行的流程实例
.processInstanceId(processInstanceId)//按照流程实例id查询
.singleResult();//返回唯一的结果集
if (pi != null){
System.out.println("当前流程在:"+pi.getActivityId());
}else {
System.out.println("流程已经结束!!");
}
}
//6,查询历史任务
@Test
public void queryHistoryTask(){
//历史任务办理人
String taskAssignee = "";
//通过流程实例id查询流程实例
List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery()//创建历史任务查询
.taskAssignee(taskAssignee)
.list();
if (list != null && list.size()>0){
for (HistoricTaskInstance task:list
) {
System.out.println("任务id:"+task.getId());
}
}
}
//7.查询历史流程实例
@Test
public void queryHistoryProcessInstance(){
String processInstance = "";
HistoricProcessInstance hpi = historyService.createHistoricProcessInstanceQuery()
.processInstanceId(processInstance)//使用流程实例id查询
.singleResult();
System.out.println("流程定义id:"+hpi.getProcessDefinitionId());
System.out.println("流程实例ID"+hpi.getId());
System.out.println(hpi.getStartTime()+"---"+hpi.getEndTime()+"---"+hpi.getDurationInMillis());
}
}
更多详细请参考:https://blog.csdn.net/qq877507054/article/details/60143099