flowable任務(wù)監(jiān)聽器和java-service依賴注入問題
前言
1. Flowable中Java服務(wù)任務(wù)的依賴注入方法,比如使用Spring的@Autowired或構(gòu)造函數(shù)注入,并確保服務(wù)任務(wù)類由Spring管理。
2. 流程引擎配置中啟用依賴注入和表達式解析的相關(guān)設(shè)置。
3. 異步任務(wù)執(zhí)行器的配置,確保其與Spring上下文集成,處理依賴注入的Bean。
4. 常見問題排查,如檢查Bean的作用域、是否正確使用delegateExpression等。
5. 可能的示例代碼或配置片段,幫助用戶理解如何正確配置。
另外,可能需要提醒用戶注意流程定義文件中的服務(wù)任務(wù)配置是否正確,比如是否使用了expression或delegateExpression來引用Spring Bean,或者是否直接指定了Java類導(dǎo)致Spring的依賴注入不生效。
最后,如果有必要,可以比較一下在非Spring環(huán)境下如何手動處理依賴注入,但大部分情況下用戶可能在使用Spring,所以重點放在Spring集成方面。
一、Java服務(wù)任務(wù)依賴注入
場景:在實現(xiàn)JavaDelegate的類中注入Spring管理的Bean(如Service、Repository)。
正確配置方法:
-
步驟1:將服務(wù)類注冊為Spring Bean
@Component("myServiceTask") // 使用名稱便于流程中引用
public class MyServiceTask implements JavaDelegate {
private final MyService myService;
@Autowired // 構(gòu)造器注入推薦
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); // 啟用異步執(zhí)行器 config.setExpressionManager(new SpringExpressionManager(applicationContext, null)); // 啟用Spring表達式 return config; }
二. 異步任務(wù)執(zhí)行器配置
當服務(wù)任務(wù)標記為異步(flowable:async="true")時,任務(wù)由異步執(zhí)行器處理。
配置異步執(zhí)行器:
@Bean public AsyncExecutor asyncExecutor(DataSource dataSource) { DefaultAsyncExecutor asyncExecutor = new DefaultAsyncExecutor(); asyncExecutor.setDataSource(dataSource); asyncExecutor.setCorePoolSize(5); // 核心線程數(shù) asyncExecutor.setMaxPoolSize(10); // 最大線程數(shù) asyncExecutor.setQueueSize(100); // 任務(wù)隊列大小 return asyncExecutor; }
在processEngineConfiguration中啟用:
config.setAsyncExecutor(asyncExecutor); config.setAsyncExecutorEnabled(true);
異步任務(wù)依賴注入要點:
-
Bean作用域:異步任務(wù)可能在新線程中運行,確保注入的Bean是線程安全的或使用
@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)。 -
事務(wù)管理:若異步任務(wù)涉及數(shù)據(jù)庫操作,需配置
@Transactional并確保事務(wù)傳播正確。
三、通過ApplicationContextAware接口的方式獲取ApplicationContext對象實例
可能的錯誤情況包括:沒有在流程引擎配置中設(shè)置asyncExecutorEnabled為true,或者在服務(wù)任務(wù)中沒有正確使用表達式導(dǎo)致注入失敗。另外,Bean的作用域問題也可能導(dǎo)致依賴注入失敗, 例如,如果Bean的作用域是原型(prototype),但在注入時可能需要不同的處理方式。以下是我通過ApplicationContextAware接口的方式獲取ApplicationContext對象實例,再通過applicationContext.getBean("myService") 方法獲取對應(yīng)的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 執(zhí)行service方法 System.out.println("==========執(zhí)行監(jiān)聽器======"); } }
四. 常見問題排查
-
錯誤:無法解析表達式
${myServiceTask}-
檢查Bean名稱是否匹配。
-
確認流程引擎配置中設(shè)置了
SpringExpressionManager。
-
-
異步任務(wù)不執(zhí)行
-
檢查
asyncExecutor是否啟動:調(diào)用asyncExecutor.start()。 -
查看日志中是否有任務(wù)提交異常。
-
-
事務(wù)不生效
-
確保異步執(zhí)行器配置了事務(wù)管理器: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) 服務(wù)任務(wù)類:
@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, "流程通知", "您的任務(wù)已處理完成。"); } }
(3) 流程定義XML:
<serviceTask id="sendEmail" flowable:delegateExpression="${emailServiceTask}" />
六.總結(jié)
-
依賴注入:確保服務(wù)任務(wù)類為Spring Bean,流程中使用
delegateExpression引用。 -
異步執(zhí)行:配置
AsyncExecutor并啟用,注意線程安全和事務(wù)。 -
ApplicationContextAware接口的方式獲取ApplicationContext對象實例
-
Spring集成:正確配置
SpringProcessEngineConfiguration以支持表達式和Bean解析。

浙公網(wǎng)安備 33010602011771號