本文主要讲解Activiti
如何在ServiceTask
中调用Spring
的Bean
,记录下解决过程和最终方案
没有采用Activi7.0
是因为7.0的资料较少,不好研究,没有使用activiti-spring-boot-starter-basic
是因为不兼容spring boot2.0+
最近在研究Activiti
与Drools
结合使用,其中会有大量的RuleTask
和ServiceTask
在使用TaskService
调用spring
的bean
时,总会报以下异常
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
<dependencies>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-engine</artifactId>
<version>6.0.0</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring</artifactId>
<version>6.0.0</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-bpmn-model</artifactId>
<version>6.0.0</version>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.9.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
- 配置
@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
中