【背景】
最近在使用activiti 并且结合spring mvc 和 mybatis 做一些简单的poc。
查阅网上的例子,很快能正确配置工作流并且走通每一步。但在深入的过程中,发现基于
JavaDelegate接口的实现类无法获取到spring 的其他 bean。
【描述】
废话不多,上干货。
public class SampleTask implements JavaDelegate { @Autowired private SampleManager sampleManager; @Override public void execute(DelegateExecution delegateExecution) {
.....
//这里一直报空指针,sampleManager为空
sampleManager.doXXX();
}
【排查思路】
1. 确保bean名字是否正确,ide直接可以跳转到SampleManager.java。配置一定没问题。
2. 调用自动装配@Autowired 的类,本身也是要被自动装配或是spring bean factory管理的。
个人认为很多人会忽略第二条。
3. 果断在SampleTask上加上@component. 依然报错。
4. 查阅资料,发现activiti 源码中,是自己new 的实例。并不是由spring bean factory管理。
【解决问题】
在activiti配置中serviceTask 下 不仅仅有 activiti:class 。还有 activiti:delegateExpression .
具体我是这样用的,
<bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
.... .... <property name="beans"> <map> <entry key="sample" value-ref="sample" /> </map> </property>
...
</bean>
<bean id="sample" class="XX.XX.XX.XX.SampleTask" />
在到工作流定义文件 xxx.bpmn20.xml 中
<serviceTask activiti:delegateExpression="${sample}" id="sample" name="sample"/>
这样使用。
再次编译部署后,可以获取到spring bean。
【个人总结】
Activiti 本身也是一个不完全依赖于spring的工作流引擎,所以默认使用activiti:class 并不是由spring去管理实例的。而spring bean 自动装配的原则也导致为什么一开始获取到的都是null.
如果总结的不正确或者不完全,希望评论指出