springboot2.0整合工作流activiti6.0,以及与业务集成时的一些坑

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_30698633/article/details/83038890

1、首先,要在springboot工程的pom文件中引入相关jar包

<dependency>
      <groupId>org.activiti</groupId>
      <artifactId>activiti-spring</artifactId>
      <version>6.0.0</version>
</dependency>

2、添加配置文件,注入activiti的service

@Configuration
public class ActivitiConfiguration {

    @Autowired
    private DataSource dataSource;
    @Autowired
    private PlatformTransactionManager platformTransactionManager;

	@Bean
	public SpringProcessEngineConfiguration springProcessEngineConfiguration(){
		SpringProcessEngineConfiguration spec = new SpringProcessEngineConfiguration();
        spec.setDataSource(dataSource);
        spec.setTransactionManager(platformTransactionManager);
		spec.setDatabaseSchemaUpdate("true");
		Resource[] resources = null;
        // 启动自动部署流程
		try {
			resources = new PathMatchingResourcePatternResolver().getResources("classpath*:bpmn/*.bpmn");
		} catch (IOException e) {
			e.printStackTrace();
		}
		spec.setDeploymentResources(resources);
		return spec;
	}
	
	@Bean
	public ProcessEngineFactoryBean processEngine(){
		ProcessEngineFactoryBean processEngineFactoryBean = new ProcessEngineFactoryBean();
		processEngineFactoryBean.setProcessEngineConfiguration(springProcessEngineConfiguration());
		return processEngineFactoryBean;
	}

	
	@Bean
	public RepositoryService repositoryService() throws Exception{
		return processEngine().getObject().getRepositoryService();
	}
	@Bean
	public RuntimeService runtimeService() throws Exception{
		return processEngine().getObject().getRuntimeService();
	}
	@Bean
	public TaskService taskService() throws Exception{
		return processEngine().getObject().getTaskService();
	}
	@Bean
	public HistoryService historyService() throws Exception{
		return processEngine().getObject().getHistoryService();
	}
	
}

3、与业务进行集成。

      这里我使用activiti变量保存流程信息,在流程执行中使用流程监听器去修改业务表。为了简单,业务表和activiti的表在一个数据库内,这样就不会涉及分布式事务的问题了,直接使用spring的事务管理器就可以控制事务的提交,回滚了。

    3.1 画流程图

     

    3.2设置流程信息

       

   3.3设置任务监听器

        这里有不同的设置方式,我这里用的是expression,这样就不用实现activiti的JavaDelegate接口了,而且同一个类中

        可以实现很多方法,就像下面的apply方法就是自定义的一个方法。(Java Class和Delegate expression都需要实现

        接口才行)。

        注意配置中的Event事件,这里可以选择监听器触发的时机,任务监听器有craete,assignment,complete,all四

       种。 连线监听器有take,还有其他监听器请自行探索。

      

 上面的apply方法中,我们可以看到有两个参数,其中execution是属于activiti内置的参数,java代码中只需要使用   DelegateExecution接收即可,从中我们可以获取流程相关的一些信息,而task是我自定义的一个参数,如果要想在

 监听器中监听,我们需要在流程变量中设置名为task的参数,变量分为全局的流程变量,局部的任务变量,和瞬时

 变量,因为我这里 task变量不需要存库,只是想在监听器中获取一下,所以这里我存储的是瞬时变量。

 注意点:因为在流程启动的时候我没有直接设置临时变量的地方,所以我是在启动流程实例的时候触发了一个监听器,

                然后在监听器中设置了的瞬时变量。

4、启动流程,并执行审核流程

     4.1 启动流程

// 这里的myProcess就是我们上面流程中设置的Id,businessKey是业务key,可以用来和
// 业务进行绑定
runtimeService.startProcessInstanceByKey("myProcess", "businessKey");

    4.2执行审核流程

// 通过业务key查询出对应的任务
Task task = taskService.createTaskQuery()
.processInstanceBusinessKey("businessKey").singleResult();
// 将相关信息放入工作流局部变量,和任务进行绑定
Map<String, Object> localVariable = new HashMap<>(2);
localVariable.put("user", "username");
localVariable.put("time" ,"2018-12-09");
taskService.setVariablesLocal(task.getId(), localVariable);

// 设置临时变量
Map<String, Object> variable = new HashMap<>(1);
variable.put("result", "pass");
// 完成任务并设置瞬时变量(这里还可以通过taskService直接设置瞬时变量)
taskService.complete(task.getId(),null,variable);

   4.3完成任务会触发我们的任务监听器(设置event为complete)

    @Transactional(rollbackFor = Exception.class)
    public void apply(DelegateExecution execution,Task task){
        // 这里可以对我们的业务表进行操作,保证业务表和工作流中的状态是匹配的
    }

  以上,权限是在业务表中进行控制的,所以的工作流执行的过程中,我没有给任务指定任何处理人(工作流不指定

 任务处理人也可以一直往下执行),在我的业务方法中,就相当于一直调用next方法,流程就会按照正常流程一直

 往下执行,直到结束。 如果是需要驳回等流程,那就需要单独处理判断了。

  如果需要设置处理人,只需要在任务的属性中进行配置即可,如下图:

总结:使用工作流有两种方式

           1、任务处理权限还是在业务表中进行控制,通过业务key查询任务并完成任务,工作流只是起一个流转以及

                保存流程历史信息的作用,对于业务来说,只要通过业务key找到流程任务,然后执行下一步即可,驳回等

                操作需要自己处理判断,然后完成任务后,自动触发作流的监听器去修改业务的具体数据。

           2、任务处理权限由工作流控制,我们在工作流中指定任务的处理人(处理人可以动态指定),然后通过处理人查

                询任务并完成任务,然后自动触发作流的监听器去修改业务的具体数据。

注意事项:1、如果想要在监听器中绑定任务变量,需要在任务监听器中进行设置任务变量,千万不要在任务之后的连

               线监听器中设置任务变量,因为在一个事务中,上一个任务属于还没有完成,所以还能设置。但是!!!这样

               设置会导致任务变量保存到act_ru_variable中,正常应该保存到act_hi_varinst中。不然设置的时候虽然不会报

               错,但是到最后结束流程的时候,你就会发现结束不了了,因为外键原因,act_ru_variable中存在任务变量没有

               删除,导出结束任务时,任务信息不能删除,然后报错!!!

                2、瞬时变量的设置问题,启动流程的时候,没有直接设置瞬时变量的地方,所以我找到了在启动时触发监听器

               设置。但是,流程如果执行到了最后,后面没有用户任务节点了,这时候,就不能设置瞬时变量了,不然activiti

               会转换类型异常,它会将瞬时变量转为全局变量类型,这时就会报错,转换异常!!!

猜你喜欢

转载自blog.csdn.net/qq_30698633/article/details/83038890