activiti第一步 -- 了解activiti、IDEA 配置activiti、测试activiti基本流程
1、什么是工作流
在了解activiti之前,先了解一下工作流系统,用官方解释就是“业务过程的部分或整体在计算机应用环境下的自动化,是对工作流程及其各操作步骤之间业务规则的抽象、概括描述”。
按照我的理解是,作为一个流程,计算机将会帮助完成其流程的自动化运转,让业务人员专注于其自身的业务,比如请假审批流程,本来是人员填写请假申请,然后递交到审核人员,审核人员审核后填写意见,然后反馈给请假人员,如果采用了工作流,那么只需要填写请假申请和填写审核意见,其它的都交由系统完成。
我认为这个是适用于业务场景复杂,且需要明确流程以及具体用户的工作,就可以采用工作流系统管理。
2、什么是activiti
那么activiti是什么,它是一种工作流引擎,用于完成工作流自动化的工作,通过计算机来达到工作流管理的效果。
用简单的话来说,它定义了一系列规则,规定了每个流程中需要的元素和各类API,将业务流程抽象化,用户只需要配置相应的流程信息,就可以达到推动业务系统的实现了。
3、activiti有什么用
简化复杂的业务流程,让业务人员专注于独立的业务,业务的流转都交由系统完成,减少了人力浪费和可能出现的差错。当然软件毕竟是软件,更重要的是制度和管理,要知道这只是让业务管理更为简单的软件。
4、我为什么要用activiti
因为开发经理要用,其实我们项目并不完全符合工作流的要求,我们用户并不专注于独立的业务,有些角色拥有跨业务查询的能力,每个流程都要看到所有数据,好在他们还是拥有独立的业务,可以利用工作流提供每个阶段拥有业务处理能力角色。
所以说我们在开发的时候既要让整个流程在我们设定的代码下运行,同时要推动工作流一步一步进行下去,而工作流提供给我们的就是该阶段的用户角色。
5、BPM和工作流区别
这两个都是有关于过程管理的概念,按照我的理解,BPM更专注于全局性的过程流程与控制,而工作流则更适用于让流程自动化的场景,工作流的发展推动了BPM的发展,而BPM的发展则更倾向于更全局的控制。
6、流程
讲完这些之后我想说说流程,流程流转于我们身边每一个环节,让流程运转的更为流畅、安全、高效,事情也能随之事半功倍,这也是管理的一部分,随着企业发展,企业越来越大,管理的难度也会随着变大,那么制度和相应的管理也要随之更改,这个时候流程的控制重要性也会越来越高,所以BPM在未来的发展会越来越凸显其重要性。
7、IDEA+SpringMVC+mysql配置activiti
以下所有配置都默认在idea已经配置好能够运行项目的情况下,不会讲什么jdk、mysql、maven如何配置
(1)IDEA actiBPM插件配置
actiBPM是一款能够让idea支持bpm文件编辑的插件,只需要在File->setting->Plugins里面安装即可,点击browse repositories搜索actiBPM下载安装,然后按提示重启idea,创建一个bpm文件就可以启动插件
(2)Maven配置
其实应该只需要activiti-engine、activiti-spring、activiti-bpmn-layout就可以了吧
<activiti.version>5.18.0</activiti.version>
<!-- activiti BEGIN -->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-engine</artifactId>
<version>${activiti.version}</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-bpmn-model</artifactId>
<version>${activiti.version}</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-bpmn-converter</artifactId>
<version>${activiti.version}</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-process-validation</artifactId>
<version>${activiti.version}</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-bpmn-layout</artifactId>
<version>${activiti.version}</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring</artifactId>
<version>${activiti.version}</version>
</dependency>
<!-- activiti END -->
(3)Spring-config-activiti 配置
在这里配置相关的数据库连接池以及工作流引擎的对象管理
<bean id="acitvityDataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<!-- 基本属性 url、user、password -->
<property name="url" value="${connection_activiti.url}"/>
<property name="username" value="${connection_activiti.username}"/>
<property name="password" value="${connection_activiti.password}"/>
</bean>
<!-- 创建事务管理器 -->
<bean id="activiti_transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="acitvityDataSource" />
</bean>
<!-- 创建流程引擎配置对象 -->
<bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
<property name="dataSource" ref="acitvityDataSource" />
<property name="transactionManager" ref="activiti_transactionManager" />
<property name="databaseSchemaUpdate" value="true" />
<!-- 使用spring的自动资源加载部署方式部署 -->
<property name="deploymentResources" value="classpath*:activiti/*.bpmn" />
</bean>
<!-- 创建流程引擎对象-->
<bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
<property name="processEngineConfiguration" ref="processEngineConfiguration" />
</bean>
<bean id="identityService" factory-bean="processEngine" factory-method="getIdentityService" />
<bean id="formService" factory-bean="processEngine" factory-method="getFormService" />
<bean id="repositoryService" factory-bean="processEngine" factory-method="getRepositoryService" />
<bean id="runtimeService" factory-bean="processEngine" factory-method="getRuntimeService" />
<bean id="taskService" factory-bean="processEngine" factory-method="getTaskService" />
<bean id="historyService" factory-bean="processEngine" factory-method="getHistoryService" />
<bean id="managementService" factory-bean="processEngine" factory-method="getManagementService" />
(4)编写Tset用例,查看是否成功配置
使用三个sql文件创建activiti需要的表
(org\activiti\activiti-engine\5.18.0\org.activiti.db.create中)
activiti.mysql.create.engine.sql
activiti.mysql.create.history.sql
activiti.mysql.create.identity.sql
另外还有一种方法:
// 如果之前没有创建activiti相关的表,调用它会自动创建,由activiti-context.xml文件内容创建
DeploymentBuilder deploymentBuilder = processEngine.getRepositoryService().createDeployment();
如果没有报错,且正常运行,那么说明就可以了,配置就到此成功了。数据库也生成了相应的数据库表。接下来就是写流程,一步步推动activiti往下走。
显示结果:
插入一大堆数据到数据库,完后模板部署,返回两个ID,使用两个ID逐步完成各项任务。
流程实例ID:10005
流程定义ID:bpmTest:1:10004
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations ={
"classpath:spring-config.xml",
"classpath:spring-mvc.xml"})
public class ActivitiTest {
@Autowired
private ProcessEngine processEngine;
@Autowired
private RuntimeService runtimeService;
@Autowired
private TaskService taskService;
@Autowired
private ManagementService managerService;
@Autowired
private IdentityService identityService;
@Autowired
private FormService formService;
@Autowired
private HistoryService historyService;
/**
*启动,创建一个流程实例
*/
@Test()
public void testCreateProcessInstance() throws Exception{
// 个人资料
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("姓名", "程序员");
variables.put("职务", "高级软件工程师");
variables.put("语言", "Java/C#");
variables.put("事务", "请假");
// 获取创建一个实例
ProcessInstance pi = runtimeService.startProcessInstanceByKey("bpmTest",variables); //这里面的值就是点击BPM页面空白处所显示的ID
System.out.println("流程实例ID:" + pi.getId());
System.out.println("流程定义ID:" + pi.getProcessDefinitionId());
}
}
6、大致activiti完整流程测试用例编写和理解
(1)第一步,启动实例,因为spring配置已经配置了该BPM路径,所以同时也会部署流程图,这一步用的也就是上面写的测试用例,这个时候就可以用两个ID完成更多的操作。
结果:
流程实例ID:12505
流程定义ID:bpmTest:2:12504
/**
* 启动并部署实例
* @throws Exception
*/
@Test()
public void testRunProcess()throws Exception{
ProcessInstance pi = runtimeService.startProcessInstanceByKey("bpmTest");
System.out.println("流程实例ID:" + pi.getId());
System.out.println("流程定义ID:" + pi.getProcessDefinitionId());
}
(2)查看个人的任务
/**
* 查看个人任务
*/
@Test()
public void searchSelfTask() throws Exception{
String assignee = "emply";
String process_id="17501"; //指的是act_ru_task中的PROC_INST_ID
List<Task> list = taskService.createTaskQuery()// 与正在执行的任务管理相关的Service
.processInstanceId(process_id) //指定任务进程
.taskAssignee(assignee)// 指定个人任务查询,指定办理人
.list();
if (list != null && list.size() > 0) {
for (Task task : list) {
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("########################################################");
}
}
}
(3)执行任务,将会流转到下一个,同时数据库中act_ru_task里面的任务状态会更新为下一个的状态,bpmTest:3:15006,生成新的任务ID,指派新的人。
public void testCommiTask() throws Exception{
String assignee="emply";
String process_id="17501";
Task task = taskService//与正在执行的任务管理相关的Service
.createTaskQuery()//创建任务查询对象
/**查询条件(where部分)*/
.processInstanceId(process_id)
.taskAssignee(assignee)//指定个人任务查询,指定办理人
.singleResult();//返回列表
//完成任务
taskService.complete(task.getId());
System.out.println("已完成任务提交");
}
(4)完成指定任务,这个时候所有任务都完成,act_ru_task中的任务消失,进入historytask中可以查询到该任务信息,到此整个小流程就此走完,还有很多东西需要继续研究,比如说回退操作、网关判断、分支等操作。接下来慢慢讲吧。
/**
* 完成指定任务
*/
@Test()
public void testComplete() throws Exception{
String taskId1="20002";
String taskId2="15011";
//完成任务的同时,设置流程变量,让流程变量判断连线该如何执行
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("flag", 0);
//完成任务
taskService.complete(taskId1,variables); //带参数完成
System.out.println("带参数的任务完成");
taskService.complete(taskId2);
System.out.println("不带参数的任务完成");
}