前言
1. Flowable中Java服务任务的依赖注入方法,比如使用Spring的@Autowired或构造函数注入,并确保服务任务类由Spring管理。
2. 流程引擎配置中启用依赖注入和表达式解析的相关设置。
3. 异步任务执行器的配置,确保其与Spring上下文集成,处理依赖注入的Bean。
4. 常见问题排查,如检查Bean的作用域、是否正确使用delegateExpression等。
5. 可能的示例代码或配置片段,帮助用户理解如何正确配置。
另外,可能需要提醒用户注意流程定义文件中的服务任务配置是否正确,比如是否使用了expression或delegateExpression来引用Spring Bean,或者是否直接指定了Java类导致Spring的依赖注入不生效。
最后,如果有必要,可以比较一下在非Spring环境下如何手动处理依赖注入,但大部分情况下用户可能在使用Spring,所以重点放在Spring集成方面。
一、Java服务任务依赖注入
场景 :在实现JavaDelegate
的类中注入Spring管理的Bean(如Service、Repository)。
正确配置方法:
- 步骤1:将服务类注册为Spring Bean
@Component("myServiceTask") // 使用名称便于流程中引用
public class MyServiceTask implements JavaDelegate {
private final MyService myService;
@Autowired // 构造器注入推荐
public MyServiceTask(MyService myService) {
this.myService = myService;
}
@Override
public void execute(DelegateExecution execution) {
myService.businessMethod();
}
}
-
步骤2:在流程定义中引用Bean
使用
delegateExpression
指向Spring Bean的名称:
<serviceTask id="serviceTask1" name="My Task" flowable:delegateExpression="${myServiceTask}" />
常见问题解决:
-
Bean注入为null:
-
确保类被Spring扫描(位于@ComponentScan路径下)。
-
检查流程定义中是否错误使用
class
属性而非delegateExpression
。 -
确认流程引擎配置启用了Spring集成。
-
-
表达式解析失败 :
在
FlowableConfig
中启用表达式解析和Spring注入:
@Bean
public SpringProcessEngineConfiguration processEngineConfiguration(DataSource dataSource, PlatformTransactionManager transactionManager) {
SpringProcessEngineConfiguration config = new SpringProcessEngineConfiguration();
config.setDataSource(dataSource);
config.setTransactionManager(transactionManager);
config.setDatabaseSchemaUpdate(Flowable.DB_SCHEMA_UPDATE_TRUE);
config.setAsyncExecutorEnabled(true); // 启用异步执行器
config.setExpressionManager(new SpringExpressionManager(applicationContext, null)); // 启用Spring表达式
return config;
}
二. 异步任务执行器配置
当服务任务标记为异步(flowable:async="true"
)时,任务由异步执行器处理。
配置异步执行器:
@Bean
public AsyncExecutor asyncExecutor(DataSource dataSource) {
DefaultAsyncExecutor asyncExecutor = new DefaultAsyncExecutor();
asyncExecutor.setDataSource(dataSource);
asyncExecutor.setCorePoolSize(5); // 核心线程数
asyncExecutor.setMaxPoolSize(10); // 最大线程数
asyncExecutor.setQueueSize(100); // 任务队列大小
return asyncExecutor;
}
在processEngineConfiguration
中启用:
config.setAsyncExecutor(asyncExecutor);
config.setAsyncExecutorEnabled(true);
异步任务依赖注入要点:
-
Bean作用域 :异步任务可能在新线程中运行,确保注入的Bean是线程安全的或使用
@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
。 -
事务管理 :若异步任务涉及数据库操作,需配置
@Transactional
并确保事务传播正确。
三、通过ApplicationContextAware接口的方式获取ApplicationContext对象实例
可能的错误情况包括:没有在流程引擎配置中设置asyncExecutorEnabled为true,或者在服务任务中没有正确使用表达式导致注入失败。另外,Bean的作用域问题也可能导致依赖注入失败,
例如,如果Bean的作用域是原型(prototype),但在注入时可能需要不同的处理方式。以下是我通过ApplicationContextAware接口的方式获取ApplicationContext对象实例,再通过applicationContext.getBean("myService")
方法获取对应的bean
代码示例:
@Component
public class MyListener implements TaskListener, ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext arg0) throws BeansException {
applicationContext = arg0;
}
@Override
public void notify(DelegateTask delegateTask) {
String processInsId = delegateTask.getProcessInstanceId();
MyService myService = (MyService) applicationContext.getBean("myService");
// TODO 执行service方法
System.out.println("==========执行监听器======");
}
}
四. 常见问题排查
-
错误:无法解析表达式
${myServiceTask}
-
检查Bean名称是否匹配。
-
确认流程引擎配置中设置了
SpringExpressionManager
。
-
-
异步任务不执行
-
检查
asyncExecutor
是否启动:调用asyncExecutor.start()
。 -
查看日志中是否有任务提交异常。
-
-
事务不生效
- 确保异步执行器配置了事务管理器:asyncExecutor.setTransactionManager(transactionManager);
五. Spring Boot集成
若使用flowable-spring-boot-starter
,简化配置如下:
(1) application.yml:
flowable:
async-executor-enabled: true
database-schema-update: true
async-executor:
core-pool-size: 5
max-pool-size: 10
queue-size: 100
(2) 服务任务类:
@Component
public class EmailServiceTask implements JavaDelegate {
private final EmailService emailService;
public EmailServiceTask(EmailService emailService) {
this.emailService = emailService;
}
@Override
public void execute(DelegateExecution execution) {
String recipient = (String) execution.getVariable("email");
emailService.send(recipient, "流程通知", "您的任务已处理完成。");
}
}
(3) 流程定义XML:
<serviceTask id="sendEmail" flowable:delegateExpression="${emailServiceTask}" />
六.总结
-
依赖注入 :确保服务任务类为Spring Bean,流程中使用
delegateExpression
引用。 -
异步执行 :配置
AsyncExecutor
并启用,注意线程安全和事务。 -
ApplicationContextAware接口的方式获取ApplicationContext对象实例
-
Spring集成 :正确配置
SpringProcessEngineConfiguration
以支持表达式和Bean解析。