Spring boot 中activiti ServiceTask 调用spring bean

本文主要讲解Activiti如何在ServiceTask中调用SpringBean,记录下解决过程和最终方案

没有采用Activi7.0是因为7.0的资料较少,不好研究,没有使用activiti-spring-boot-starter-basic是因为不兼容spring boot2.0+

最近在研究ActivitiDrools 结合使用,其中会有大量的RuleTaskServiceTask

在使用TaskService调用springbean时,总会报以下异常

org.activiti.engine.ActivitiException: Could not execute service task expression
    at org.activiti.engine.impl.bpmn.behavior.ServiceTaskExpressionActivityBehavior.execute(ServiceTaskExpressionActivityBehavior.java:91) ~[activiti-engine-6.0.0.jar:6.0.0]
  
Caused by: org.activiti.engine.ActivitiException: Error while evaluating expression: ${testService.print(name)}

环境

  • Spring-boot 2.1.9
  • activiti6.0.0
  • Drools 7.0.0.Final

背景

只是有一堆数据需要经过规则引擎,设置不同的字段,在根据不同的字段调用不同的服务;使用流程引擎与规则引擎结合的方式最为方便;

  • UserTask流程不会暂停,一次执行完成
  • 不需要记录执行过程

所以采用H2内存数据库ProcessEngineConfiguration采用内存的方式

ProcessEngineConfiguration.createStandaloneInMemProcessEngineConfiguration()

改造后项目

此处没有列出Drools 7.0.0.Final相关的jar

  • pom.xml

  
    org.activiti
    activiti-engine
    6.0.0
  
  
    org.activiti
    activiti-spring
    6.0.0
  
  
    org.activiti
    activiti-bpmn-model
    6.0.0
  
  
    com.h2database
    h2
  
  
    org.springframework.boot
    spring-boot-starter-web
  
  
    org.springframework.boot
    spring-boot-starter-jdbc
  


  
    
      org.springframework.boot
      spring-boot-dependencies
      2.1.9.RELEASE
      pom
      import
    
  

  • 配置
@Component
public class Config {
    /**
     * 数据源配置
     * @return
     */
    @Bean
    public DataSource dataSource() {
        return DataSourceBuilder.create()
                .username("sa")
                .password("")
                .url("jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=false").build();
    }

    /***
     * 事务管理
     * SpringProcessEngineConfiguration 需要设置此参数,否则会抛异常
     * @return
     */
    @Bean
    public PlatformTransactionManager transactionManager(){
        DataSourceTransactionManager transactionManager=new DataSourceTransactionManager();
        transactionManager.setDataSource(dataSource());
        return transactionManager;
    }

    /**
     * 此处改造是关键点(1)
     * @return
     */
    @Bean
    public SpringProcessEngineConfiguration springProcessEngineConfiguration() {
        SpringProcessEngineConfiguration processEngineConfiguration = new SpringProcessEngineConfiguration();
        processEngineConfiguration.setDataSource(dataSource());
        processEngineConfiguration.setTransactionManager(transactionManager());
        processEngineConfiguration.setDatabaseSchemaUpdate("true");
        return processEngineConfiguration;
    }

    @Autowired
    private ApplicationContext applicationContext;
    @Bean
    public ProcessEngine processEngine() throws Exception {
        //ProcessEngine 的获取方式需要使用这种方式
        ProcessEngine processEngine = springProcessEngineBean().getObject();
        //而不能使用springProcessEngineConfiguration().buildProcessEngine()的方式获取
        return processEngine;
    }
        /**
        *
        *此处改造是关键点(1)
        * @return
        */
    public ProcessEngineFactoryBean springProcessEngineBean() {
        ProcessEngineFactoryBean processEngineFactoryBean = new ProcessEngineFactoryBean();
        processEngineFactoryBean.setProcessEngineConfiguration(springProcessEngineConfiguration());
        processEngineFactoryBean.setApplicationContext(applicationContext);
        return processEngineFactoryBean;
    }
}
  • 关键代码分析
public ProcessEngine getObject() throws Exception {
        this.configureExpressionManager();
        this.configureExternallyManagedTransactions();
        if (this.processEngineConfiguration.getBeans() == null) {
            this.processEngineConfiguration.setBeans(new SpringBeanFactoryProxyMap(this.applicationContext));
        }

        this.processEngine = this.processEngineConfiguration.buildProcessEngine();
        return this.processEngine;
    }

从上面代码不难看出只要设置了applicationContext,activi即会将spring上下文中bean设置到processEngineConfiguration

源码 https://github.com/jiabiaoli/activiti-hello

你可能感兴趣的:(Spring boot 中activiti ServiceTask 调用spring bean)