关于flowable执行监听器,spring注入失败的问题
问题
在使用flowable执行监听器的时候,使用spring注入失败
SendOutService 注入失败.png
通过查看spring容器管理的bean发现:
image.jpeg
spring容器是有ProcessCompleteListener
image.jpeg
同时发现spring容器也是有SendOutService
但是,为什么会注入失败呢?
原因
一开始,认为没有注入进去是spring的问题。
image.png
在通过debug spring源码,发现在spring启动时,通过org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean去创建,管理了ProcessCompleteListener。
在网上查找相关资料,有说流程引擎启动时,依赖注入还未初始化完成。也有说是因为spring加载时机的原因 。
但是,通过查看实例发现。此刻是有2个实例,一个实例SendOutService是注入成功的。另一个则是一个实例SendOutService是注入失败的。猜测一个是spring管理的bean,另一个是flowable引擎new 出来的。
通过源码发现
org.flowable.engine.impl.bpmn.listener.ListenerNotificationHelper#executeExecutionListeners
image.jpeg
在ListenerNotificationHelper中,通过listenerFactory.createClassDelegateExecutionListener(listener);去创建ExecutionListener。
进一步去查看。
image.png image.jpeg
在org.flowable.engine.impl.bpmn.helper.DefaultClassDelegateFactory#create(java.lang.String, java.util.List<org.flowable.engine.impl.bpmn.parser.FieldDeclaration>)中的确通过new ClassDelegate出来的。
image.jpeg
最后再去执行notify方法。
为了验证的确是flowable引擎new 出来的,我将@Component注释掉,依然可以进入执行监听器。
image.png
解决
既然不能通过spring去注入service。我们可以通过ApplicationContextUtil.getBean(RuntimeService.class);去获取到Spring容器中已初始化的bean。
此外:根据flowable文档,也可以通过Expression的方式进行注入,不过该种方法,我并未实验,大家可以自己去尝试。
image.png