工作流概述
工作流(Workflow),就是“业务过程的部分或整体在计算机应用环境下的自动化”,它主要解决的是“使在“多个参与者”之间按照某种“预定义的规则”传递文档、信息或任务的过程自动进行,从而实现某个预期的业务目标,或者促使此目标的实现”。
通俗的说,流程就是多个人在一起合作完成某件事情的步骤,把步骤变成计算机能理解的形式就是工作流。
Activiti核心配置文件
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 创建ProcessEngineConfiguration对象的bean -->
<bean id="processEngineConfiguration"
class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
<!-- 配置对象的配置信息 :连接数据库,使用MyBatis连接池 -->
<property name="jdbcUrl"
value="jdbc:mysql:///activiti?createDatabaseIfNotExist=true" />
<property name="jdbcDriver" value="com.mysql.jdbc.Driver" />
<property name="jdbcUsername" value="root" />
<property name="jdbcPassword" value="root" />
<!--
databaseSchemaUpdate: 设置流程引擎启动和关闭时如何处理数据库表。
false(默认):检查数据库表的版本和依赖库的版本, 如果版本不匹配就抛出异常。
true: 构建流程引擎时,执行检查,如果需要就执行更新。 如果表不存在,就创建。
create-drop: 构建流程引擎时创建数据库表,关闭流程引擎时删除这些表。
-->
<property name="databaseSchemaUpdate" value="true" />
</bean>
</beans>
Activiti流程图
1、部署的定义
@Test
public void deployTest() {
//获取核心对象
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//获取服务
RepositoryService repositoryService = processEngine.getRepositoryService();
//操作
DeploymentBuilder deploymentBuilder = repositoryService.createDeployment();
deploymentBuilder
.name("请假流程")//设置部署名称
.addClasspathResource("ProcessVarTest.bpmn")
.addClasspathResource("ProcessVarTest.png");
deploymentBuilder.deploy();
}
2、启动流程实例
@Test
public void startProcessTest() throws Exception {
//创建核心对象
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//获取服务
RuntimeService runtimeService = processEngine.getRuntimeService();
String processDefinitionKey="ProcessVarTestId";
Map<String,Object> variables=new HashMap<>();
variables.put("剩余年假天数", 3);
variables.put("剩余病假天数", 10);
//操作:启动的时候设置流程变量
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey, variables);
System.out.println("pId="+processInstance.getId());//2501
}
3、设置流程变量
@Test
public void setVarTest() throws Exception {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
TaskService taskService = processEngine.getTaskService();
String processInstanceId="2501";
String assignee="小莉";
//通过任务服务获取这个流程实例中 小莉的唯一的一个任务
Task task = taskService.createTaskQuery()
.processInstanceId(processInstanceId)//在一次流程实例中一个人的任务是唯一的
.taskAssignee(assignee)
.singleResult();
System.out.println(task);
//设置一个流程变量
String taskId = task.getId();
taskService.setVariable(taskId, "请假人", assignee);
Map<String,Object> variables=new HashMap<>();
variables.put("请假原因","想男朋友了");//设置String
variables.put("请假天数", 3);//设置Integer
variables.put("是否扣工资",true);//设置boolean:存long型:1true;0false
variables.put("请假开始时间", new Date());//设置Date类型
variables.put("扣多少钱", 666.666d);//设置Double
//设置多个流程变量:
taskService.setVariables(taskId, variables);
//完成任务的时候设置:
Map<String,Object> variables1=new HashMap<>();
variables1.put("叫老板", "亲爱的老板,我真的要回去找男朋友,很急的。。。。。");
taskService.complete(taskId, variables1);
}
说明:
1)流程变量的作用域就是流程实例,所以只要设置就行了,不用管在哪个阶段设置
2)基本类型设置流程变量,在taskService中使用任务ID,定义流程变量的名称,设置流程变量的值。
3)Javabean类型设置流程变量,需要这个javabean实现了Serializable接口
4)设置流程变量的时候,向act_ru_variable这个表添加数据
4、获取流程变量
/**
* 获取流程变量的方式:
* @throws Exception
*/
@Test
public void getVarTest() throws Exception {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
TaskService taskService = processEngine.getTaskService();
String processInstanceId="2501";
String assignee="美丽";
//一个流程实例中,一个办理人只有一个任务
Task task = taskService.createTaskQuery().
processInstanceId(processInstanceId).
taskAssignee(assignee)
.singleResult();
String taskId=task.getId();
Map<String, Object> variables = taskService.getVariables(taskId);
System.out.println("所有的流程变量:"+variables);
Map<String, Object> variables2 = taskService.getVariables(taskId, Arrays.asList("请假天数","叫老板"));
System.out.println("批量获取流程变量:"+variables2);
Double money = (Double) taskService.getVariable(taskId, "扣多少钱");
System.out.println("获取一个变量:"+money);
Date beginDate = taskService.getVariable(taskId, "请假开始时间",Date.class);
System.out.println("获取一个变量:"+beginDate);
}
说明:
1)流程变量的获取针对流程实例(即1个流程),每个流程实例获取的流程变量时不同的
2)使用基本类型获取流程变量,在taskService中使用任务ID,流程变量的名称,获取流程变量的值。
3)Javabean类型设置获取流程变量,除了需要这个javabean实现了Serializable接口外,还要求流程变量对象的属性不能发生变化,否则抛出异常。解决方案,固定序列化ID
5、.模拟流程变量的设置和获取的场景
/**
* 模拟查看设置变量和获取变量的api,目的是整理属性api
* //设置流程变量:4种
//①:启动流程的时候设置
//②:任务完成的时候设置
//③:runtimeService设置
//④:taskService设置
//获取流程变量:2种
//①:runtimeService获取变量
//②:taskService获取变量
* @throws Exception
*/
@Test
public void setVarAndGetVarTest() throws Exception {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RuntimeService runtimeService = processEngine.getRuntimeService();
TaskService taskService = processEngine.getTaskService();
//设置流程变量:4种
//①:启动流程的时候设置
//runtimeService.startProcessInstanceByKey(processDefinitionKey, variables);
//②:任务完成的时候设置
//taskService.complete(taskId, variables);
//③:runtimeService设置
//runtimeService.setVariable(executionId, variableName, value);//存一个
//runtimeService.setVariables(executionId, variables);//存多个
//④:taskService设置
//taskService.setVariable(taskId, variableName, value);//存一个
//taskService.setVariables(taskId, variables);//存多个
//获取流程变量:2种
//①:runtimeService获取变量
//runtimeService.getVariables(executionId)//获取所有
//runtimeService.getVariables(executionId, variableNames)//批量获取
//runtimeService.getVariable(executionId, variableName);//获取一个,但是要强转
//runtimeService.getVariable(executionId, variableName, variableClass)//获取一个,带泛型,不强转
//②:taskService获取变量
//taskService.getVariables(taskId)//获取所有
//taskService.getVariables(taskId, variableNames)//批量获取
//taskService.getVariable(taskId, variableName);//获取一个,但是要强转
//taskService.getVariable(taskId, variableName, variableClass)//获取一个,带泛型,不强转
}
说明:
1)RuntimeService对象可以设置流程变量和获取流程变量
2)TaskService对象可以设置流程变量和获取流程变量
3)流程实例启动的时候可以设置流程变量
4)任务办理完成的时候可以设置流程变量
5)流程变量可以通过名称/值的形式设置单个流程变量
6)流程变量可以通过Map集合,同时设置多个流程变量
Map集合的key表示流程变量的名称
Map集合的value表示流程变量的值
注意:
1.流程变量应该可以被所有的执行对象获取(只要流程实例不结束,流程变量可以在任何地方获取)
2.流程变量是可以覆盖的
3.如果存放domain实体类的话就需要这个实体类实现序列化接口 Serializable