Acitivi 流程框架入门

0.前言

  一开始就听概念有点不好理解,等学完activiti之后你会自然而然的有一个自己的定义。我的理解是它可以用来做流程管理,最经典的就是请假流程:需要找谁请假,需要谁来批假。还有身份审核:你需要上传什么文件来提交审核,又是谁来审核等等这些都涉及到流程管理。如果你的程序拓展性不高的话,当新的需求进来你就很难完成了。这就提出了需要使用到流程框架——Activiti。它的官网在这里:https://www.activiti.org/ 当然了学习一门技术首要看它的开发者文档:https://www.activiti.org/5.x/userguide/

1.入门配置

  activiti需要使用到数据库,我使用的是mysql。Activi是和spring进行整合的,所以需要有spring相关的配置,这里就不赘述。然后需要导入activiti的maven

<dependency>
      <groupId>org.activiti</groupId>
      <artifactId>activiti-engine</artifactId>
      <version>5.15.1</version>
</dependency>

然后我们配置spring,在我的项目中我放了两个spring,这个专门用来处理activit,另外一个spring配置文件是用来配置数据源,事务管理器等等,我们的重点是activiti所以就不多说哪些东西了。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jee="http://www.springframework.org/schema/jee"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
       http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
       http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
       http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.1.xsd">
  
    <bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
    	<property name="dataSource" ref="dataSource" /><!--这个是配置数据源的,我放在了另一个spring中  -->
    	<property name="transactionManager" ref="transactionManager" /><!--这是事务管理器,也另一个文件中使用ref就可以引用 -->
    	<property name="databaseSchemaUpdate" value="true" />
    	<property name="jobExecutorActivate" value="true" />
    	<property name="labelFontName" value="宋体" />
    	<property name="activityFontName" value="宋体" />
        <property name="customFormTypes">
          <list>
            <bean class="org.activiti.explorer.form.UserFormType"/>
            <bean class="org.activiti.explorer.form.ProcessDefinitionFormType"/> 
            <bean class="org.activiti.explorer.form.MonthFormType"/>   
          </list>
        </property>
    </bean>
    <!--这个是activiti的核心 这个叫流程引擎,activiti就是使用ProcessEngineFactoryBean来和其他框架做整合的-->
    <bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean" destroy-method="destroy">
  	    <property name="processEngineConfiguration" ref="processEngineConfiguration" />
    </bean>
     <!--这个是一个储存库服务-->
    <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" />
</beans>

然后我们创建一个测试类,测试这个程序能跑起来吗

public class ActivitiTest {
	//创建一个spring容器,我有两个spring文件所以使用了spring-*.xml
    ApplicationContext ioc = new ClassPathXmlApplicationContext("spring/spring-*.xml");
    @Test
    public void test_01(){
        ProcessEngine processEngine = (ProcessEngine) ioc.getBean("processEngine");
        System.out.println("程序测试完成"+processEngine);
    }
}

这个过程可能会慢一点,因为他需要在数据库中创建23张表。这些表都是以act开头
在这里插入图片描述

act_ge_bytearray二进制数据表
act_ge_property属性数据表存储整个流程引擎级别的数据,初始化表结构时,会默认插入三条记录,

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_re_deployment部署信息表
act_re_model流程设计模型部署表
act_re_procdef流程定义数据表

act_ru_event_subscr  throwEvent、catchEvent时间监听信息表
act_ru_execution运行时流程执行实例表
act_ru_identitylink运行时流程人员表,主要存储任务节点与参与者的相关信息
act_ru_job运行时定时任务数据表
act_ru_task运行时任务节点表
act_ru_variable运行时流程变量数据表

程序执行完成:
在这里插入图片描述

2.安装插件

  我们在进行流程管理的时候首先需要进行流程的定义,比如请假找谁请,请几天。这个是需要先定义的。定义这个实际上是一个xml文件的配置,但是手写的话会非常麻烦效率不高。安装一个图形化的设计插件,可以很快的进行定义。看官方文档发现他们好像就做了一个eclipse的插件。我用的开发工具是idea。idea的插件名称叫actiBPM但是我发现在使用的时候老是出一些问题,而且这个插件在14年就没更新了。然后又选择了另外一个插件:Yaoqiang BPMN Editor 大佬一般用什么插件也可以给我推荐一些,不太懂这个。最后我选择官方提供的eclipse的插件。把用它生成的流程定义文件直接考到idea中使用。
Name:Activiti BPMN 2.0 designer
Location:http://activiti.org/designer/update/
在这里插入图片描述
如果你觉得这个在线下载太慢,或者安装失败你可以在https://github.com/Activiti/Activiti-Designer/releases 这里下载最新的插件,这是官方的开源库。下载activiti-designer-5.18.0.zip 的zip,然后解压把这个文件夹放在你eclipse安装目录下的dropins文件夹下:
在这里插入图片描述
文件目录是这样的
在这里插入图片描述
然后重启你的eclipse你就会发现在创建文件的时候有这个选项了:
在这里插入图片描述
这样插件的安装就完成诺。

3.流程定义

在eclipse中创建activiti文件,画出流程图
在这里插入图片描述
文件----》右键----》open whith----》xml Editor.就会看到这个图生产的xml文件了
在这里插入图片描述
因为我主要使用idea所以就把这个文件拷贝到idea中。(以xml方式来保存)

4.流程部署

编写程序

public class ActivitiTest {
    ApplicationContext ioc = new ClassPathXmlApplicationContext("spring/spring-*.xml");

    @Test
    public void test_01(){
        ProcessEngine processEngine = ioc.getBean(ProcessEngine.class);
        System.out.println("程序测试完成"+processEngine);
		//拿到一个储存库的服务
        RepositoryService repositoryService = processEngine.getRepositoryService();
        //从repositoryService中创建一个部署并且添加之前画好的流程定义文件,然后部署就可以获取到一个部署对象了
        Deployment deploy = repositoryService.createDeployment().addClasspathResource("MyProcess.bpmn").deploy();
    }
}

运行程序过后,通过观察可以发现有三张表发生了数据变化:act_ge_bytearray二进制数据表(主要是用来储存bpmn文件的图片会自动转换成png格式,当然还有他本身的文件)、act_re_deployment部署信息表(部署的时间这些详细的信息)、act_re_procdef流程定义数据表。

5.流程的查询

public class ActivitiTest {
    ApplicationContext ioc = new ClassPathXmlApplicationContext("spring/spring-*.xml");
    ProcessEngine processEngine = ioc.getBean(ProcessEngine.class);
    //流程查询
    @Test
    public void test_02(){
        RepositoryService repositoryService = processEngine.getRepositoryService();
        //获取流程定义查询对象
        ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
        List<ProcessDefinition> list = processDefinitionQuery.list();
        for (ProcessDefinition processDefinition : list) {
            System.out.println("id="+processDefinition.getId());
            System.out.println("name="+processDefinition.getName());
        }
    }
}

这是查询流程定义那张表的数据’
在这里插入图片描述
查询流程的定义主要是使用ProcessDefinitionQuery类,里面的方法还是挺多的
在这里插入图片描述

5.创建流程实例

public class ActivitiTest {
    ApplicationContext ioc = new ClassPathXmlApplicationContext("spring/spring-*.xml");
    ProcessEngine processEngine = ioc.getBean(ProcessEngine.class);
    //创建流程实例
    @Test
    public void test_03(){
        //获取一个定义查询
        ProcessDefinitionQuery processDefinitionQuery = processEngine.getRepositoryService().createProcessDefinitionQuery();
        //查询最后一个定义的流程
        ProcessDefinition processDefinition = processDefinitionQuery.latestVersion().singleResult();
        //获取运行时服务
        RuntimeService runtimeService = processEngine.getRuntimeService();
        //获取流程实例对象
        ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinition.getId());

    }
}

执行完程序:act_hi_actinst历史节点表、act_hi_procinst历史流程实例表、act_hi_taskinst历史任务实例表、act_ru_execution运行时流程执行实例表、act_ru_task运行时任务节点表。这些表的数据发生了变化

5.流程的任务

可以指定这个任务是由谁来完成的。先创建一个定义的流程。注意设置审批人是谁,将来就以他的身份来审批
在这里插入图片描述
重新部署一下这个流程。在部署表里面会发现新的数据
在这里插入图片描述
然后运行创建流程实例的代码,然后就会看到这样一条数据。这个是运行时流程人员表,主要储存参与者相关的信息。
在这里插入图片描述
此时呢,任务已经走到了第一个任务。接下来获取人员审批的这个任务。

public class ActivitiTest {
   ApplicationContext ioc = new ClassPathXmlApplicationContext("spring/spring-*.xml");
   ProcessEngine processEngine = ioc.getBean(ProcessEngine.class);
   //获取任务
   @Test
   public void test_04(){
       //获取一个任务服务
       TaskService taskService = processEngine.getTaskService();
       //获取一个任务查询对象
       TaskQuery taskQuery = taskService.createTaskQuery();
       //通过委托人来查所以任务
       List<Task> list = taskQuery.taskAssignee("任导").list();
       System.out.println("****************************");
       for (Task task : list) {
           System.out.println(task.getName());//获取任务名称
       }

   }
}

这样我们就拿到了一个任务了,这些信息存在了act_ru_task里面
在这里插入图片描述
那么如果这个时候我们去查系主任审批的这个任务,就会查不到,因为流程还没有到达。
如果这时我们需要通过这个流程,就可以使用

taskService.complete(task.getId());//表示任导完成这个任务,通过该流程

这个时候任务表里面是这样的。之前是显示辅导员审批
在这里插入图片描述
活动表里面:显示了流程,开始–》辅导员审批—》系主任审批
在这里插入图片描述
接着把系主任的任务也完成。

6.历史流程查询

public class ActivitiTest {
    ApplicationContext ioc = new ClassPathXmlApplicationContext("spring/spring-*.xml");
    ProcessEngine processEngine = ioc.getBean(ProcessEngine.class);
    //历史任务查询
    @Test
    public void test_05(){
        //获取历史服务
        HistoryService historyService = processEngine.getHistoryService();
        //获取历史流程
        HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService.createHistoricProcessInstanceQuery();
        //根据id已经完成的流程
        HistoricProcessInstance historicProcessInstance = historicProcessInstanceQuery.processInstanceId("301").finished().singleResult();

        System.out.println(historicProcessInstance.toString());
     
    }
}

7.任务的领取

一个任务可能派发给多个人。或者一个组。那么就需要在定义流程的时候需要指定一个组。所以我在一次重新画一个流程。一个任务由一个组来管理
在这里插入图片描述
把原来的数据删一下。重新部署

public class ActivitiTest {
    ApplicationContext ioc = new ClassPathXmlApplicationContext("spring/spring-*.xml");
    ProcessEngine processEngine = ioc.getBean(ProcessEngine.class);
    //领取任务
    @Test
    public void test_06(){
        TaskService taskService = processEngine.getTaskService();
        TaskQuery taskQuery = taskService.createTaskQuery();
        //根据组名来获取任务集
        List<Task> groups = taskQuery.taskCandidateGroup("groups").list();
        for (Task task : groups) {
            //将任务指派给  任导
            taskService.claim(task.getId(),"任导");
        }
	}
}

6.排他网关

相当于判断语句,请假天数大于某值,就走另一个流程
在这里插入图片描述
先启动一下任务实例

public class ActivitiTest {
    ApplicationContext ioc = new ClassPathXmlApplicationContext("spring/spring-*.xml");
    ProcessEngine processEngine = ioc.getBean(ProcessEngine.class);
    //排他网关
    @Test
    public void test_07(){
        ProcessDefinition processDefinition = processEngine.getRepositoryService().createProcessDefinitionQuery().latestVersion().singleResult();

        RuntimeService runtimeService = processEngine.getRuntimeService();
        Map<String, Object> varibales = new HashMap<>();
        varibales.put("day",2);
        ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinition.getId(), varibales);
    }

然后让导员通过审批

public void test_08(){
        TaskService taskService = processEngine.getTaskService();
        //获取一个任务查询对象
        TaskQuery taskQuery = taskService.createTaskQuery();
        //通过委托人来查所以任务
        List<Task> list = taskQuery.taskAssignee("任导").list();
        System.out.println("****************************");
        for (Task task : list) {
            System.out.println(task.getName());
            taskService.complete(task.getId());//表示任导完成这个任务,通过该流程
        }
    }

当day等于2的时候,就会完成完成全部任务
在这里插入图片描述
接下来把day设置为5,然后辅导员通过审批,这个时候流程就会自动走到系主任审批这里
在这里插入图片描述
然后系主任继续通过审批:
在这里插入图片描述
网关还包含并行网关,相当于逻辑并,和包含网关,相当于逻辑或

7.结束

这是我学习ativiti的一个总结,不对之处!请多指教。

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值