BOS项目10:activiti,历史数据操作,流程变量,任务组,监听器,网关,spring整合

本文主要是介绍BOS项目10:activiti,历史数据操作,流程变量,任务组,监听器,网关,spring整合,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!



目录(?)[-]

  1.   1    历史数据查询
  2. 2    流程变量
  3. 3    组任务操作
  4. 4    监听器
  5. 5    网关
  6. 6    spring整合activiti框架

内容:

1、历史数据查询(历史流程实例数据、历史任务数据、历史活动数据)

2、流程变量

3、组任务(候选人、候选组)

4、监听器(执行、任务)

5、网关(排他、并行)

6、spring整合activiti

 
1.    历史数据查询

历史是一个组件,它可以捕获发生在进程执行中的信息并永久的保存,与运行时数据不同的是,当流程实例运行完成之后它还会存在于数据库中。

在流程引擎配置对象中可以设置历史记录规则:




1.1   查询历史流程实例数据

表中内容包含已经完成的流程和正在进行的流程

[java]  view plain  copy
 
  在CODE上查看代码片 派生到我的代码片
  1. //查询历史流程实例数据  
  2. @Test  
  3. public void test4(){  
  4.     //历史流程实例查询对象,查询表:act_hi_procinst  
  5.     HistoricProcessInstanceQuery query = pe.getHistoryService().createHistoricProcessInstanceQuery();  
  6.     List<HistoricProcessInstance> list = query.list();  
  7.     for (HistoricProcessInstance pi : list) {  
  8.         System.out.println(pi.getId() + " " + pi.getStartTime() + " " + pi.getEndTime());  
  9.     }  
  10. }  

 

 

1.2   历史任务数据

表中内容包含已经完成的任务和正在进行的任务

[java]  view plain  copy
 
  在CODE上查看代码片 派生到我的代码片
  1. //查询历史任务数据  
  2. @Test  
  3. public void test5(){  
  4.     //历史任务实例查询对象,查询表:act_hi_taskinst  
  5.     HistoricTaskInstanceQuery query = pe.getHistoryService().createHistoricTaskInstanceQuery();  
  6.     query.orderByProcessInstanceId();  
  7.     query.orderByHistoricTaskInstanceStartTime().asc();  
  8.     List<HistoricTaskInstance> list = query.list();  
  9.     for (HistoricTaskInstance task : list) {  
  10.         System.out.println(task.getProcessInstanceId() + " " + task.getName());  
  11.     }  
  12. }  

 

 

1.3   历史活动数据

 包含一个活动(流程上的节点)的执行信息

 

[java]  view plain  copy
 
  在CODE上查看代码片 派生到我的代码片
  1. //查询历史活动数据  
  2. @Test  
  3. public void test6(){  
  4.     //历史活动实例查询对象,查询表:act_hi_actinst  
  5.     HistoricActivityInstanceQuery query = pe.getHistoryService().createHistoricActivityInstanceQuery();  
  6.     query.orderByProcessInstanceId();  
  7.     query.orderByHistoricActivityInstanceStartTime().asc();  
  8.     List<HistoricActivityInstance> list = query.list();  
  9.     for (HistoricActivityInstance ai : list) {  
  10.         System.out.println(ai.getProcessInstanceId() + " " + ai.getActivityName());  
  11.     }  
  12. }  

 

2.    流程变量


 


流程变量的作用域范围是流程实例。也就是说各个流程实例的流程变量是不相互影响的





 

 

2.1   设置流程变量


    方式一:启动流程实例时设置流程变量

[java]  view plain  copy
 
  在CODE上查看代码片 派生到我的代码片
  1. // 设置流程变量方式一:启动流程实例时设置  
  2. @Test  
  3. public void test2() {  
  4.     String processDefinitionKey = "qjlc";  
  5.     Map<String, Object> variables = new HashMap<String, Object>();  
  6.     variables.put("k1""v1");  
  7.     variables.put("k2"200);  
  8.     variables.put("username""小明");//从session中动态获取当前登录用户的用户名  
  9.     ProcessInstance processInstance = pe.getRuntimeService()  
  10.             .startProcessInstanceByKey(processDefinitionKey, variables);  
  11.     System.out.println(processInstance.getId());  
  12. }  

 

    方式二:办理任务时设置流程变量

[java]  view plain  copy
 
  在CODE上查看代码片 派生到我的代码片
  1. // 设置流程变量方式二:办理任务时设置  
  2. @Test  
  3. public void test3() {  
  4.     // pe.getTaskService().createTaskQuery().taskAssignee("张三").list();  
  5.     String taskId = "1502";  
  6.     Map<String, Object> variables = new HashMap<>();  
  7.     variables.put("qjts"5);  
  8.     variables.put("qjyy""不想上班");  
  9.     pe.getTaskService().complete(taskId, variables);  
  10. }  

 

    方式三:使用RuntimeService的set方法设置流程变量

 

[java]  view plain  copy
 
  在CODE上查看代码片 派生到我的代码片
  1. // 设置流程变量方式三:RuntimeService的Set方法设置  
  2. @Test  
  3. public void test4() {  
  4.     String executionId = "801";// 流程实例ID  
  5.     String variableName = "k3";// 流程变量的key  
  6.     Object value = "v3";// 流程变量的value  
  7.     // 设置一个流程变量  
  8.     // pe.getRuntimeService().setVariable(executionId, variableName, value);  
  9.   
  10.     Map<String, Object> variables = new HashMap<String, Object>();  
  11.     variables.put("k4""v4");  
  12.     variables.put("k4""v5");  
  13.     variables.put("user"new User(10"abc"20));  
  14.     // 设置多个流程变量  
  15.     pe.getRuntimeService().setVariables(executionId, variables);  
  16. }  

    方式四:使用TaskService的set方法设置流程变量

[java]  view plain  copy
 
  在CODE上查看代码片 派生到我的代码片
  1. // 设置流程变量方式四:TaskService的Set方法设置  
  2. @Test  
  3. public void test5() {  
  4.     String taskId = "1004";// 任务ID  
  5.     // 设置一个流程变量  
  6.     pe.getTaskService().setVariable(taskId, "k5""v5");  
  7.     // 设置多个流程变量  
  8.     // pe.getTaskService().setVariables(taskId, variables);  
  9. }  

 

注:自定义类如果需要设置流程变量,必须实现Serializable序列化接口。

 

2.2   获取流程变量


流程变量是从act_ru_variable这个表中读出来的


    使用RuntimeService的get方法获取

[java]  view plain  copy
 
  在CODE上查看代码片 派生到我的代码片
  1. // 获取流程变量方式一:使用RuntimeService的get方法获取  
  2. @Test  
  3. public void test6() {  
  4.     String executionId = "801";  
  5.     // 获取一个流程变量  
  6.     Object v = pe.getRuntimeService().getVariable(executionId, "k1");  
  7.     System.out.println(v);  
  8.     // 获取多个流程变量  
  9.     Map<String, Object> variables = pe.getRuntimeService().getVariables(  
  10.             executionId);  
  11.     Set<String> keySet = variables.keySet();  
  12.     for (String key : keySet) {  
  13.         Object value = variables.get(key);  
  14.         System.out.println(key + " = " + value);  
  15.     }  
  16. }  

 

    使用TaskService的get方法获取


与runtimeService结果一样

注:存储的对象参数,再获取的时候必须与存储时对象结构一样(也可以添加固定序列化id),如果发生改变会抛异常,无法反序列化

[java]  view plain  copy
 
  在CODE上查看代码片 派生到我的代码片
  1. // 获取流程变量方式二:使用TaskService的get方法获取  
  2. @Test  
  3. public void test7() {  
  4.     String taskId = "1004";  
  5.     // 获取一个流程变量  
  6.     User user = (User) pe.getTaskService().getVariable(taskId , "user");  
  7.     System.out.println(user);  
  8.     // 获取当前任务所在流程实例(801)范围内所有的流程变量  
  9.     Map<String, Object> variables = pe.getTaskService().getVariables(taskId);  
  10.     Set<String> keySet = variables.keySet();  
  11.     for (String key : keySet) {  
  12.         Object value = variables.get(key);  
  13.         System.out.println(key + " = " + value);  
  14.     }  
  15. }  

 

    使用框架提供的表达式获取

 

 


 

3.    组任务操作


个人任务(私人任务):由某一个人负责办理的任务为个人任务

组任务(公共任务):多个人作为候选人,都可以办理的任务

3.1   候选人

所有组(公共)任务的assignee属性为空



    查询组任务

[java]  view plain  copy
 
  在CODE上查看代码片 派生到我的代码片
  1. // 查询组任务  
  2. @Test  
  3. public void test5() {  
  4.     TaskQuery query = pe.getTaskService().createTaskQuery();  
  5.     // 组任务查询  
  6.     query.taskCandidateUser("user1");  
  7.     List<Task> list = query.list();  
  8.     for (Task task : list) {  
  9.         System.out.println(task.getId() + " " + task.getName());  
  10.     }  
  11. }  

 

    拾取组任务(将组任务变为个人任务)

 

[java]  view plain  copy
 
  在CODE上查看代码片 派生到我的代码片
  1. // 拾取组任务  
  2. @Test  
  3. public void test6() {  
  4.     String taskId = "2302";  
  5.     String userId = "user1";  
  6.     pe.getTaskService().claim(taskId, userId);  
  7. }  

    退回组任务(,将个人任务变为组任务)

[java]  view plain  copy
 
  在CODE上查看代码片 派生到我的代码片
  1. // 退回组任务  
  2. @Test  
  3. public void test7() {  
  4.     String taskId = "2302";  
  5.     pe.getTaskService().setAssignee(taskId, null);  
  6. }  


 

3.2   候选组(重点)


 

 

    创建组

与项目中的角色表保持一致

[java]  view plain  copy
 
  在CODE上查看代码片 派生到我的代码片
  1. // 创建组,操作的表:act_id_group  
  2. @Test  
  3. public void test2() {  
  4.     // 实际项目中group表中的数据和系统表角色表保持一致  
  5.     Group group = new GroupEntity();  
  6.     group.setId("财务人员组");  
  7.     group.setName("财务人员组");  
  8.     pe.getIdentityService().saveGroup(group);  
  9. }  


    创建用户

与项目中的用户表保持一致 

import org.activiti.engine.identity.User;

[java]  view plain  copy
 
  在CODE上查看代码片 派生到我的代码片
  1. // 创建用户,操作的表:act_id_user  
  2. @Test  
  3. public void test3() {  
  4.     // 实际项目中act_id_user表中的数据和系统表用户表(t_user)保持一致  
  5.     User user = new UserEntity();  
  6.     user.setId("002");  
  7.     user.setFirstName("小王");  
  8.     pe.getIdentityService().saveUser(user);  
  9. }  


    将用户加入到组中

[java]  view plain  copy
 
  在CODE上查看代码片 派生到我的代码片
  1. // 将用户加入到组中  
  2. @Test  
  3. public void test4() {  
  4.     pe.getIdentityService().createMembership("002""财务人员组");  
  5. }  

查询任务使用候选人(既候选人id)进行过滤

[java]  view plain  copy
 
  在CODE上查看代码片 派生到我的代码片
  1. //查询组任务  
  2. @Test  
  3. public void test8(){  
  4.     TaskQuery query = pe.getTaskService().createTaskQuery();  
  5.     //组任务查询  
  6.     //query.taskCandidateGroup("财务人员组");  
  7.     query.taskCandidateUser("001");//使用候选人进行过滤  
  8.     List<Task> list = query.list();  
  9.     for (Task task : list) {  
  10.         System.out.println(task.getId() + " " + task.getName());  
  11.     }  
  12. }  
  13.   
  14. //拾取组任务  
  15. @Test  
  16. public void test9(){  
  17.     String taskId = "3002";  
  18.     String userId = "001";  
  19.     pe.getTaskService().claim(taskId, userId);  
  20. }  


4.    监听器


在流程中我们有时会对整个流程或者一个节点的某种状态做出相应的处理。这时就会用到监听器。
在Activiti中流程的监听主要分为两大类,执行监听器任务监听器。


4.1   执行监听器

监听流程实例的开始事件和结束事件

执行监听器可以执行外部Java代码或执行表达式,当流程定义中发生了某个事件。

 可以捕获的事件有:
流程实例的启动和结束。
选中一条连线。
节点的开始和结束。
网关的开始和结束。
中间事件的开始和结束。
开始事件结束或结束事件开始。


    按照框架的要求编写一个监听器类,必须实现org.activiti.engine.delegate.ExecutionListener接口 

[java]  view plain  copy
 
  在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.  * 自定义一个监听器类 
  3.  * 
  4.  */  
  5. public class MyExecutionListener1 implements ExecutionListener {  
  6.   
  7.     public void notify(DelegateExecution execution) throws Exception {  
  8.         String processInstanceId = execution.getProcessInstanceId();  
  9.         String eventName = execution.getEventName();  
  10.         Set<String> variableNames = execution.getVariableNames();  
  11.         Map<String, Object> variables = execution.getVariables();  
  12.         String processDefinitionId = execution.getProcessDefinitionId();  
  13.         System.out.println("自定义的监听器执行了,监听器到事件:" + eventName);  
  14.     }  
  15.   
  16. }  

    注册监听器

执行监听器支持以下属性:

event(必选):任务监听器会被调用的任务类型。 可能的类型为:

    start:流程节点创建后触发。

    end:当任务完成,并尚未从运行数据中删除时触发。

    take:任务完成后,流程流出时触发(监听一条连线的执行,配置在sequenceFlow节点的内部,只有task一种事件)


使用图形界面注册监听器


 

4.2   任务监听器

*监听任务相关的事件,如任务的创建事件,任务的办理事件

*任务监听器可以在发生对应的任务相关事件时执行自定义java逻辑 或表达式。
*任务监听器只能添加到流程定义中的用户任务中 


    按照框架的要求编写监听器类,实现TaskListener接口

 

[java]  view plain  copy
 
  在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.  * 自定义任务监听器 
  3.  * 
  4.  */  
  5. public class MyTaskListener1 implements TaskListener{  
  6.     public void notify(DelegateTask task) {  
  7.         String id = task.getId();  
  8.         String name = task.getName();  
  9.         String assignee = task.getAssignee();  
  10.         Date createTime = task.getCreateTime();  
  11.         String eventName = task.getEventName();  
  12.         String processInstanceId = task.getProcessInstanceId();  
  13.         Map<String, Object> variables = task.getVariables();  
  14.         System.out.println("自定义任务监听器执行了,任务:[" + name + "] 被创建了,负责人为:" + assignee);  
  15.     }  
  16. }  

    注册监听器

任务监听器支持以下属性:

       event(必选):任务监听器会被调用的任务类型。 可能的类型为:

       create:任务创建并设置所有属性后触发。

       assignment:任务分配给一些人时触发。 当流程到达userTask,assignment事件 会在create事件之前发生。 这样的顺序似乎不自然,但是原因很简单:当获得create时间时, 我们想获得任务的所有属性,包括执行人。

      complete:当任务完成,并尚未从运行数据中删除时触发。



 

5.    网关

*网关用来控制流程的流向。
*网关显示成菱形图形,内部有有一个小图标。 图标表示网关的类型。


5.1   排他网关

特点:只能有一个分支执行。

1.一个排他网关对应一个以上的顺序流
2.由排他网关流出的顺序流都有个conditionExpression元素,在内部维护返回boolean类型的决策结果。
3.决策网关只会返回一条结果。当流程执行到排他网关时,流程引擎会自动检索网关出口,

从上到下检索如果发现第一条决策结果为true或者没有设置条件的(默认为成立),则流出。


 

5.2   并行网关

网关也可以表示流程中的并行情况。
最简单的并行网关是parallelGateWay,它允许将流程 分成多条分支,也可以把多条分支 汇聚到一起。

图形标记
并行网关显示成一个普通网关(菱形)内部是一个“加号”图标, 表示“与(AND)”语义。


特点:多个分支同时执行。

1.并行网关的功能是基于进入和外出的顺序流的:

       分支(fork): 并行后的所有外出顺序流,为每个顺序流都创建一个并发分支。

       汇聚(join): 所有到达并行网关,在此等待的进入分支,直到所有进入顺序流的分支都到达以后, 流程就会通过汇聚网关。

2.并行网关的进入和外出都是使用相同节点标示

3.如果同一个并行网关有多个进入和多个外出顺序流,它就同时具有分支和汇聚功能。 这时,网关会先汇聚所有进入的顺序流,然后再切分成多个并行分支。

4.并行网关不会解析条件。即使顺序流中定义了条件,也会被忽略。

5.并行网关不需要是“平衡的”(比如,对应并行网关的进入和外出节点数目相等)


 

表中数据(流程实例表):

 

表中数据(任务表):

 

 

6.    spring整合activiti框架

和Spring的集成主要就是把Activiti的主要对象交给Spring容器管理。

第一步:提供spring配置文件,配置数据源、事务管理器、spring提供的流程引擎配置对象、流程引擎工厂bean

[html]  view plain  copy
 
  在CODE上查看代码片 派生到我的代码片
  1. <beans xmlns="http://www.springframework.org/schema/beans"  
  2.     xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans   
  5.                         http://www.springframework.org/schema/beans/spring-beans.xsd  
  6.                         http://www.springframework.org/schema/context   
  7.                         http://www.springframework.org/schema/context/spring-context-2.5.xsd  
  8.                         http://www.springframework.org/schema/tx   
  9.                         http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">  
  10.     <!-- 数据源信息 -->  
  11.     <bean id="dataSource"  
  12.         class="org.springframework.jdbc.datasource.DriverManagerDataSource">  
  13.         <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>  
  14.         <property name="url" value="jdbc:mysql:///activiti_day2"></property>  
  15.         <property name="username" value="root"></property>  
  16.         <property name="password" value="root"></property>  
  17.     </bean>  
  18.   
  19.     <!-- 事务管理器 -->  
  20.     <bean id="transactionManager"  
  21.         class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
  22.         <property name="dataSource" ref="dataSource" />  
  23.     </bean>  
  24.   
  25.     <!-- 配置流程引擎配置对象 -->  
  26.     <bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">  
  27.         <!-- 注入数据源 -->  
  28.         <property name="dataSource" ref="dataSource"></property>  
  29.         <!-- 注入事务管理器 -->  
  30.         <property name="transactionManager" ref="transactionManager"></property>  
  31.         <!-- 注入自动建表设置 -->  
  32.         <property name="databaseSchemaUpdate" value="true"></property>  
  33.     </bean>  
  34.   
  35.     <!-- 提供工厂bean,创建流程引擎对象 -->  
  36.     <bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">  
  37.         <property name="processEngineConfiguration" ref="processEngineConfiguration"></property>  
  38.     </bean>  
  39.       
  40.     <!-- 配置Service -->  
  41.     <bean id="repService" factory-bean="processEngine" factory-method="getRepositoryService"></bean>  
  42. </beans>  
 

第二步测试:读取spring配置文件,创建spring工厂,从spring工厂中获取一个流程引擎对象

 

[java]  view plain  copy
 
  在CODE上查看代码片 派生到我的代码片
  1. public class SpringActivitiTest {  
  2.     public static void main(String[] args) {  
  3.         // 创建spring工厂,从spring工厂中获取一个流程引擎对象  
  4.         ApplicationContext ctx = new ClassPathXmlApplicationContext(  
  5.                 "com/itheima/activiti/spring/applicationContext.xml");  
  6.         /*ProcessEngine processEngine = (ProcessEngine) ctx 
  7.                 .getBean("processEngine"); 
  8.         List<ProcessDefinition> list = processEngine.getRepositoryService() 
  9.                 .createProcessDefinitionQuery().list(); 
  10.         for (ProcessDefinition processDefinition : list) { 
  11.             System.out.println(processDefinition.getName()); 
  12.         }*/  
  13.           
  14.         RepositoryService service = (RepositoryService) ctx.getBean("repService");  
  15.         List<ProcessDefinition> list = service.createProcessDefinitionQuery().list();  
  16.         for (ProcessDefinition processDefinition : list) {  
  17.             System.out.println(processDefinition.getName());  
  18.         }  
  19.     }  
  20. }  

 

将activiti加入进bos项目


jar包:去掉重复的spring等 jar包

把配置中引擎对象 工厂bean 和service 复制进bos spring配置文件即可

测试:配置正确启动项目会生成23张表

目录(?)[-]

  1.   1    历史数据查询
  2. 2    流程变量
  3. 3    组任务操作
  4. 4    监听器
  5. 5    网关
  6. 6    spring整合activiti框架

内容:

1、历史数据查询(历史流程实例数据、历史任务数据、历史活动数据)

2、流程变量

3、组任务(候选人、候选组)

4、监听器(执行、任务)

5、网关(排他、并行)

6、spring整合activiti

 
1.    历史数据查询

历史是一个组件,它可以捕获发生在进程执行中的信息并永久的保存,与运行时数据不同的是,当流程实例运行完成之后它还会存在于数据库中。

在流程引擎配置对象中可以设置历史记录规则:




1.1   查询历史流程实例数据

表中内容包含已经完成的流程和正在进行的流程

[java]  view plain  copy
 
  在CODE上查看代码片 派生到我的代码片
  1. //查询历史流程实例数据  
  2. @Test  
  3. public void test4(){  
  4.     //历史流程实例查询对象,查询表:act_hi_procinst  
  5.     HistoricProcessInstanceQuery query = pe.getHistoryService().createHistoricProcessInstanceQuery();  
  6.     List<HistoricProcessInstance> list = query.list();  
  7.     for (HistoricProcessInstance pi : list) {  
  8.         System.out.println(pi.getId() + " " + pi.getStartTime() + " " + pi.getEndTime());  
  9.     }  
  10. }  

 

 

1.2   历史任务数据

表中内容包含已经完成的任务和正在进行的任务

[java]  view plain  copy
 
  在CODE上查看代码片 派生到我的代码片
  1. //查询历史任务数据  
  2. @Test  
  3. public void test5(){  
  4.     //历史任务实例查询对象,查询表:act_hi_taskinst  
  5.     HistoricTaskInstanceQuery query = pe.getHistoryService().createHistoricTaskInstanceQuery();  
  6.     query.orderByProcessInstanceId();  
  7.     query.orderByHistoricTaskInstanceStartTime().asc();  
  8.     List<HistoricTaskInstance> list = query.list();  
  9.     for (HistoricTaskInstance task : list) {  
  10.         System.out.println(task.getProcessInstanceId() + " " + task.getName());  
  11.     }  
  12. }  

 

 

1.3   历史活动数据

 包含一个活动(流程上的节点)的执行信息

 

[java]  view plain  copy
 
  在CODE上查看代码片 派生到我的代码片
  1. //查询历史活动数据  
  2. @Test  
  3. public void test6(){  
  4.     //历史活动实例查询对象,查询表:act_hi_actinst  
  5.     HistoricActivityInstanceQuery query = pe.getHistoryService().createHistoricActivityInstanceQuery();  
  6.     query.orderByProcessInstanceId();  
  7.     query.orderByHistoricActivityInstanceStartTime().asc();  
  8.     List<HistoricActivityInstance> list = query.list();  
  9.     for (HistoricActivityInstance ai : list) {  
  10.         System.out.println(ai.getProcessInstanceId() + " " + ai.getActivityName());  
  11.     }  
  12. }  

 

2.    流程变量


 


流程变量的作用域范围是流程实例。也就是说各个流程实例的流程变量是不相互影响的





 

 

2.1   设置流程变量


    方式一:启动流程实例时设置流程变量

[java]  view plain  copy
 
  在CODE上查看代码片 派生到我的代码片
  1. // 设置流程变量方式一:启动流程实例时设置  
  2. @Test  
  3. public void test2() {  
  4.     String processDefinitionKey = "qjlc";  
  5.     Map<String, Object> variables = new HashMap<String, Object>();  
  6.     variables.put("k1""v1");  
  7.     variables.put("k2"200);  
  8.     variables.put("username""小明");//从session中动态获取当前登录用户的用户名  
  9.     ProcessInstance processInstance = pe.getRuntimeService()  
  10.             .startProcessInstanceByKey(processDefinitionKey, variables);  
  11.     System.out.println(processInstance.getId());  
  12. }  

 

    方式二:办理任务时设置流程变量

[java]  view plain  copy
 
  在CODE上查看代码片 派生到我的代码片
  1. // 设置流程变量方式二:办理任务时设置  
  2. @Test  
  3. public void test3() {  
  4.     // pe.getTaskService().createTaskQuery().taskAssignee("张三").list();  
  5.     String taskId = "1502";  
  6.     Map<String, Object> variables = new HashMap<>();  
  7.     variables.put("qjts"5);  
  8.     variables.put("qjyy""不想上班");  
  9.     pe.getTaskService().complete(taskId, variables);  
  10. }  

 

    方式三:使用RuntimeService的set方法设置流程变量

 

[java]  view plain  copy
 
  在CODE上查看代码片 派生到我的代码片
  1. // 设置流程变量方式三:RuntimeService的Set方法设置  
  2. @Test  
  3. public void test4() {  
  4.     String executionId = "801";// 流程实例ID  
  5.     String variableName = "k3";// 流程变量的key  
  6.     Object value = "v3";// 流程变量的value  
  7.     // 设置一个流程变量  
  8.     // pe.getRuntimeService().setVariable(executionId, variableName, value);  
  9.   
  10.     Map<String, Object> variables = new HashMap<String, Object>();  
  11.     variables.put("k4""v4");  
  12.     variables.put("k4""v5");  
  13.     variables.put("user"new User(10"abc"20));  
  14.     // 设置多个流程变量  
  15.     pe.getRuntimeService().setVariables(executionId, variables);  
  16. }  

    方式四:使用TaskService的set方法设置流程变量

[java]  view plain  copy
 
  在CODE上查看代码片 派生到我的代码片
  1. // 设置流程变量方式四:TaskService的Set方法设置  
  2. @Test  
  3. public void test5() {  
  4.     String taskId = "1004";// 任务ID  
  5.     // 设置一个流程变量  
  6.     pe.getTaskService().setVariable(taskId, "k5""v5");  
  7.     // 设置多个流程变量  
  8.     // pe.getTaskService().setVariables(taskId, variables);  
  9. }  

 

注:自定义类如果需要设置流程变量,必须实现Serializable序列化接口。

 

2.2   获取流程变量


流程变量是从act_ru_variable这个表中读出来的


    使用RuntimeService的get方法获取

[java]  view plain  copy
 
  在CODE上查看代码片 派生到我的代码片
  1. // 获取流程变量方式一:使用RuntimeService的get方法获取  
  2. @Test  
  3. public void test6() {  
  4.     String executionId = "801";  
  5.     // 获取一个流程变量  
  6.     Object v = pe.getRuntimeService().getVariable(executionId, "k1");  
  7.     System.out.println(v);  
  8.     // 获取多个流程变量  
  9.     Map<String, Object> variables = pe.getRuntimeService().getVariables(  
  10.             executionId);  
  11.     Set<String> keySet = variables.keySet();  
  12.     for (String key : keySet) {  
  13.         Object value = variables.get(key);  
  14.         System.out.println(key + " = " + value);  
  15.     }  
  16. }  

 

    使用TaskService的get方法获取


与runtimeService结果一样

注:存储的对象参数,再获取的时候必须与存储时对象结构一样(也可以添加固定序列化id),如果发生改变会抛异常,无法反序列化

[java]  view plain  copy
 
  在CODE上查看代码片 派生到我的代码片
  1. // 获取流程变量方式二:使用TaskService的get方法获取  
  2. @Test  
  3. public void test7() {  
  4.     String taskId = "1004";  
  5.     // 获取一个流程变量  
  6.     User user = (User) pe.getTaskService().getVariable(taskId , "user");  
  7.     System.out.println(user);  
  8.     // 获取当前任务所在流程实例(801)范围内所有的流程变量  
  9.     Map<String, Object> variables = pe.getTaskService().getVariables(taskId);  
  10.     Set<String> keySet = variables.keySet();  
  11.     for (String key : keySet) {  
  12.         Object value = variables.get(key);  
  13.         System.out.println(key + " = " + value);  
  14.     }  
  15. }  

 

    使用框架提供的表达式获取

 

 


 

3.    组任务操作


个人任务(私人任务):由某一个人负责办理的任务为个人任务

组任务(公共任务):多个人作为候选人,都可以办理的任务

3.1   候选人

所有组(公共)任务的assignee属性为空



    查询组任务

[java]  view plain  copy
 
  在CODE上查看代码片 派生到我的代码片
  1. // 查询组任务  
  2. @Test  
  3. public void test5() {  
  4.     TaskQuery query = pe.getTaskService().createTaskQuery();  
  5.     // 组任务查询  
  6.     query.taskCandidateUser("user1");  
  7.     List<Task> list = query.list();  
  8.     for (Task task : list) {  
  9.         System.out.println(task.getId() + " " + task.getName());  
  10.     }  
  11. }  

 

    拾取组任务(将组任务变为个人任务)

 

[java]  view plain  copy
 
  在CODE上查看代码片 派生到我的代码片
  1. // 拾取组任务  
  2. @Test  
  3. public void test6() {  
  4.     String taskId = "2302";  
  5.     String userId = "user1";  
  6.     pe.getTaskService().claim(taskId, userId);  
  7. }  

    退回组任务(,将个人任务变为组任务)

[java]  view plain  copy
 
  在CODE上查看代码片 派生到我的代码片
  1. // 退回组任务  
  2. @Test  
  3. public void test7() {  
  4.     String taskId = "2302";  
  5.     pe.getTaskService().setAssignee(taskId, null);  
  6. }  


 

3.2   候选组(重点)


 

 

    创建组

与项目中的角色表保持一致

[java]  view plain  copy
 
  在CODE上查看代码片 派生到我的代码片
  1. // 创建组,操作的表:act_id_group  
  2. @Test  
  3. public void test2() {  
  4.     // 实际项目中group表中的数据和系统表角色表保持一致  
  5.     Group group = new GroupEntity();  
  6.     group.setId("财务人员组");  
  7.     group.setName("财务人员组");  
  8.     pe.getIdentityService().saveGroup(group);  
  9. }  


    创建用户

与项目中的用户表保持一致 

import org.activiti.engine.identity.User;

[java]  view plain  copy
 
  在CODE上查看代码片 派生到我的代码片
  1. // 创建用户,操作的表:act_id_user  
  2. @Test  
  3. public void test3() {  
  4.     // 实际项目中act_id_user表中的数据和系统表用户表(t_user)保持一致  
  5.     User user = new UserEntity();  
  6.     user.setId("002");  
  7.     user.setFirstName("小王");  
  8.     pe.getIdentityService().saveUser(user);  
  9. }  


    将用户加入到组中

[java]  view plain  copy
 
  在CODE上查看代码片 派生到我的代码片
  1. // 将用户加入到组中  
  2. @Test  
  3. public void test4() {  
  4.     pe.getIdentityService().createMembership("002""财务人员组");  
  5. }  

查询任务使用候选人(既候选人id)进行过滤

[java]  view plain  copy
 
  在CODE上查看代码片 派生到我的代码片
  1. //查询组任务  
  2. @Test  
  3. public void test8(){  
  4.     TaskQuery query = pe.getTaskService().createTaskQuery();  
  5.     //组任务查询  
  6.     //query.taskCandidateGroup("财务人员组");  
  7.     query.taskCandidateUser("001");//使用候选人进行过滤  
  8.     List<Task> list = query.list();  
  9.     for (Task task : list) {  
  10.         System.out.println(task.getId() + " " + task.getName());  
  11.     }  
  12. }  
  13.   
  14. //拾取组任务  
  15. @Test  
  16. public void test9(){  
  17.     String taskId = "3002";  
  18.     String userId = "001";  
  19.     pe.getTaskService().claim(taskId, userId);  
  20. }  


4.    监听器


在流程中我们有时会对整个流程或者一个节点的某种状态做出相应的处理。这时就会用到监听器。
在Activiti中流程的监听主要分为两大类,执行监听器任务监听器。


4.1   执行监听器

监听流程实例的开始事件和结束事件

执行监听器可以执行外部Java代码或执行表达式,当流程定义中发生了某个事件。

 可以捕获的事件有:
流程实例的启动和结束。
选中一条连线。
节点的开始和结束。
网关的开始和结束。
中间事件的开始和结束。
开始事件结束或结束事件开始。


    按照框架的要求编写一个监听器类,必须实现org.activiti.engine.delegate.ExecutionListener接口 

[java]  view plain  copy
 
  在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.  * 自定义一个监听器类 
  3.  * 
  4.  */  
  5. public class MyExecutionListener1 implements ExecutionListener {  
  6.   
  7.     public void notify(DelegateExecution execution) throws Exception {  
  8.         String processInstanceId = execution.getProcessInstanceId();  
  9.         String eventName = execution.getEventName();  
  10.         Set<String> variableNames = execution.getVariableNames();  
  11.         Map<String, Object> variables = execution.getVariables();  
  12.         String processDefinitionId = execution.getProcessDefinitionId();  
  13.         System.out.println("自定义的监听器执行了,监听器到事件:" + eventName);  
  14.     }  
  15.   
  16. }  

    注册监听器

执行监听器支持以下属性:

event(必选):任务监听器会被调用的任务类型。 可能的类型为:

    start:流程节点创建后触发。

    end:当任务完成,并尚未从运行数据中删除时触发。

    take:任务完成后,流程流出时触发(监听一条连线的执行,配置在sequenceFlow节点的内部,只有task一种事件)


使用图形界面注册监听器


 

4.2   任务监听器

*监听任务相关的事件,如任务的创建事件,任务的办理事件

*任务监听器可以在发生对应的任务相关事件时执行自定义java逻辑 或表达式。
*任务监听器只能添加到流程定义中的用户任务中 


    按照框架的要求编写监听器类,实现TaskListener接口

 

[java]  view plain  copy
 
  在CODE上查看代码片 派生到我的代码片
  1. /** 
  2.  * 自定义任务监听器 
  3.  * 
  4.  */  
  5. public class MyTaskListener1 implements TaskListener{  
  6.     public void notify(DelegateTask task) {  
  7.         String id = task.getId();  
  8.         String name = task.getName();  
  9.         String assignee = task.getAssignee();  
  10.         Date createTime = task.getCreateTime();  
  11.         String eventName = task.getEventName();  
  12.         String processInstanceId = task.getProcessInstanceId();  
  13.         Map<String, Object> variables = task.getVariables();  
  14.         System.out.println("自定义任务监听器执行了,任务:[" + name + "] 被创建了,负责人为:" + assignee);  
  15.     }  
  16. }  

    注册监听器

任务监听器支持以下属性:

       event(必选):任务监听器会被调用的任务类型。 可能的类型为:

       create:任务创建并设置所有属性后触发。

       assignment:任务分配给一些人时触发。 当流程到达userTask,assignment事件 会在create事件之前发生。 这样的顺序似乎不自然,但是原因很简单:当获得create时间时, 我们想获得任务的所有属性,包括执行人。

      complete:当任务完成,并尚未从运行数据中删除时触发。



 

5.    网关

*网关用来控制流程的流向。
*网关显示成菱形图形,内部有有一个小图标。 图标表示网关的类型。


5.1   排他网关

特点:只能有一个分支执行。

1.一个排他网关对应一个以上的顺序流
2.由排他网关流出的顺序流都有个conditionExpression元素,在内部维护返回boolean类型的决策结果。
3.决策网关只会返回一条结果。当流程执行到排他网关时,流程引擎会自动检索网关出口,

从上到下检索如果发现第一条决策结果为true或者没有设置条件的(默认为成立),则流出。


 

5.2   并行网关

网关也可以表示流程中的并行情况。
最简单的并行网关是parallelGateWay,它允许将流程 分成多条分支,也可以把多条分支 汇聚到一起。

图形标记
并行网关显示成一个普通网关(菱形)内部是一个“加号”图标, 表示“与(AND)”语义。


特点:多个分支同时执行。

1.并行网关的功能是基于进入和外出的顺序流的:

       分支(fork): 并行后的所有外出顺序流,为每个顺序流都创建一个并发分支。

       汇聚(join): 所有到达并行网关,在此等待的进入分支,直到所有进入顺序流的分支都到达以后, 流程就会通过汇聚网关。

2.并行网关的进入和外出都是使用相同节点标示

3.如果同一个并行网关有多个进入和多个外出顺序流,它就同时具有分支和汇聚功能。 这时,网关会先汇聚所有进入的顺序流,然后再切分成多个并行分支。

4.并行网关不会解析条件。即使顺序流中定义了条件,也会被忽略。

5.并行网关不需要是“平衡的”(比如,对应并行网关的进入和外出节点数目相等)


 

表中数据(流程实例表):

 

表中数据(任务表):

 

 

6.    spring整合activiti框架

和Spring的集成主要就是把Activiti的主要对象交给Spring容器管理。

第一步:提供spring配置文件,配置数据源、事务管理器、spring提供的流程引擎配置对象、流程引擎工厂bean

[html]  view plain  copy
 
  在CODE上查看代码片 派生到我的代码片
  1. <beans xmlns="http://www.springframework.org/schema/beans"  
  2.     xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"  
  3.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  4.     xsi:schemaLocation="http://www.springframework.org/schema/beans   
  5.                         http://www.springframework.org/schema/beans/spring-beans.xsd  
  6.                         http://www.springframework.org/schema/context   
  7.                         http://www.springframework.org/schema/context/spring-context-2.5.xsd  
  8.                         http://www.springframework.org/schema/tx   
  9.                         http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">  
  10.     <!-- 数据源信息 -->  
  11.     <bean id="dataSource"  
  12.         class="org.springframework.jdbc.datasource.DriverManagerDataSource">  
  13.         <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>  
  14.         <property name="url" value="jdbc:mysql:///activiti_day2"></property>  
  15.         <property name="username" value="root"></property>  
  16.         <property name="password" value="root"></property>  
  17.     </bean>  
  18.   
  19.     <!-- 事务管理器 -->  
  20.     <bean id="transactionManager"  
  21.         class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
  22.         <property name="dataSource" ref="dataSource" />  
  23.     </bean>  
  24.   
  25.     <!-- 配置流程引擎配置对象 -->  
  26.     <bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">  
  27.         <!-- 注入数据源 -->  
  28.         <property name="dataSource" ref="dataSource"></property>  
  29.         <!-- 注入事务管理器 -->  
  30.         <property name="transactionManager" ref="transactionManager"></property>  
  31.         <!-- 注入自动建表设置 -->  
  32.         <property name="databaseSchemaUpdate" value="true"></property>  
  33.     </bean>  
  34.   
  35.     <!-- 提供工厂bean,创建流程引擎对象 -->  
  36.     <bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">  
  37.         <property name="processEngineConfiguration" ref="processEngineConfiguration"></property>  
  38.     </bean>  
  39.       
  40.     <!-- 配置Service -->  
  41.     <bean id="repService" factory-bean="processEngine" factory-method="getRepositoryService"></bean>  
  42. </beans>  
 

第二步测试:读取spring配置文件,创建spring工厂,从spring工厂中获取一个流程引擎对象

 

[java]  view plain  copy
 
  在CODE上查看代码片 派生到我的代码片
  1. public class SpringActivitiTest {  
  2.     public static void main(String[] args) {  
  3.         // 创建spring工厂,从spring工厂中获取一个流程引擎对象  
  4.         ApplicationContext ctx = new ClassPathXmlApplicationContext(  
  5.                 "com/itheima/activiti/spring/applicationContext.xml");  
  6.         /*ProcessEngine processEngine = (ProcessEngine) ctx 
  7.                 .getBean("processEngine"); 
  8.         List<ProcessDefinition> list = processEngine.getRepositoryService() 
  9.                 .createProcessDefinitionQuery().list(); 
  10.         for (ProcessDefinition processDefinition : list) { 
  11.             System.out.println(processDefinition.getName()); 
  12.         }*/  
  13.           
  14.         RepositoryService service = (RepositoryService) ctx.getBean("repService");  
  15.         List<ProcessDefinition> list = service.createProcessDefinitionQuery().list();  
  16.         for (ProcessDefinition processDefinition : list) {  
  17.             System.out.println(processDefinition.getName());  
  18.         }  
  19.     }  
  20. }  

 

将activiti加入进bos项目


jar包:去掉重复的spring等 jar包

把配置中引擎对象 工厂bean 和service 复制进bos spring配置文件即可

测试:配置正确启动项目会生成23张表

这篇关于BOS项目10:activiti,历史数据操作,流程变量,任务组,监听器,网关,spring整合的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/369141

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

Security OAuth2 单点登录流程

单点登录(英语:Single sign-on,缩写为 SSO),又译为单一签入,一种对于许多相互关连,但是又是各自独立的软件系统,提供访问控制的属性。当拥有这项属性时,当用户登录时,就可以获取所有系统的访问权限,不用对每个单一系统都逐一登录。这项功能通常是以轻型目录访问协议(LDAP)来实现,在服务器上会将用户信息存储到LDAP数据库中。相同的,单一注销(single sign-off)就是指

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory