Activiti6 TaskListener expression调用SpringBean时FixedValue为null
Activiti 6的activiti:field字段注入逻辑仅对delegateExpression声明的任务监听器生效。当你使用expression属性通过UEL直接调用Spring Bean方法时,引擎不会解析<activiti:taskListener>节点下配置的field属性,也不会执行字段注入逻辑,因此类中的taskName成员变量始终为null,调用时自然抛出空指针。
根据你的业务场景二选一即可:
方案1:使用
delegateExpression配置监听器,走原生字段注入逻辑
这是Activiti官方推荐的监听器使用方式,配置修改如下:<activiti:taskListener event="create" delegateExpression="${myService}"> <activiti:field name="taskName"> <activiti:string><![CDATA[text]]></activiti:string> </activiti:field> </activiti:taskListener>对应Spring Bean需要实现
TaskListener接口,重写notify方法:@Service("myService") public class MyService implements TaskListener { private FixedValue taskName; public FixedValue getTaskName() { return taskName; } public void setTaskName(FixedValue taskName) { this.taskName = taskName; } @Override public void notify(DelegateTask task) { // 此处可正常获取注入的taskName,无空指针 String taskNameText = taskName.getExpressionText(); // 编写业务逻辑 } }注意:如果该Bean是Spring单例模式,不要将注入的字段存在成员变量中,避免多流程并发时值互相覆盖。单例场景下可以直接在方法中通过
task.getListenerField("taskName")获取当前监听器绑定的FixedValue对象,无需定义成员变量接收注入。方案2:保留
expression调用方式,直接通过方法传参
如果不想让业务Bean实现TaskListener接口,可以直接把需要的参数写在UEL表达式中传入,无需配置field节点:<activiti:taskListener event="create" expression="${myService.method(task, 'text')}"> </activiti:taskListener>对应方法修改参数列表直接接收值即可,不需要定义FixedValue类型成员变量:
public void method(DelegateTask task, String taskName){ // 直接使用传入的taskName即可 System.out.println(taskName); }如果需要传递流程动态变量,直接在表达式中取值即可,例如
${myService.method(task, execution.getVariable('bizTaskName'))}。
内容的提问来源于stack exchange,提问作者user10950078

