看到很多文章写监听器然而大多数只是说任务监听器和事务监听器,如果要做统一的处理比如整个流程结束了我要做处理业务数据,不可能对每个流程都添加一个监听器,而使用flowable全局监听器就能处理这些需要统一处理的操作,全局监听主要有两种使用方式
1.实现FilowableEventLister
代码如下:
@Component
public class GlobalTaskListener implements FlowableEventListener{
protected Logger logger = LoggerFactory.getLogger(this.getClass());
RepositoryService repositoryService;
RuntimeService runtimeService;
HistoryService historyService;
private TaskService taskService;
``
@Override
public void onEvent(FlowableEvent event) {
//可以看到这个地方可以获取流程实例引擎和流程定义 其实任务实体、流程历史数据等等也是也够拿到的比较强大,但是缺点就是只有一个FlowableEvent 参数需要去做转换
FlowableEngineEventImpl engineEvent = (FlowableEngineEventImpl)
System.out.println("状态类型:" + engineEvent.getType());
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
.processDefinitionId(engineEvent.getProcessDefinitionId())
.singleResult();
;
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
.processInstanceId(engineEvent.getProcessInstanceId())
.singleResult();
//业务数据
}
}
同时还需要写一个类继承ApplicationListener
@Configuration
public class FlowableGlobListenerConfig implements ApplicationListener<ContextRefreshedEvent> {
@Autowired
private SpringProcessEngineConfiguration configuration;
@Autowired
private GlobalTaskListener globalTaskListener;
@Autowired
private RuntimeService runtimeService;
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
FlowableEventDispatcher dispatcher = configuration.getEventDispatcher();
//任务创建全局监听
dispatcher.addEventListener(globalTaskListener, FlowableEngineEventType.PROCESS_COMPLETED);
dispatcher.addEventListener(globalTaskListener, FlowableEngineEventType.TASK_COMPLETED);
dispatcher.addEventListener(globalTaskListener, FlowableEngineEventType.TASK_CREATED);
}
flowchatableEngineEventType是处理事件的类型比如任务完成或者流程结束监听等等方便我们这个时候要处理业务系统的数据
2.继承AbstractFlowableEngineEventListener
@Component
public class GlobalTaskListener extends AbstractFlowableEngineEventListener
显然方式二更简单细看源码其实AbstractFlowableEngineEventListener的父类已
同时也要像方式一一样写一个配置类实现ApplicationListener因为代码一样就不重复写了
经实现了FilowableEventLister做了处理所以更方便
然而当我们使用@Autowired 还是 @Resource注入bean时却会报错 提示注入的bean为空,主要还是因为spring加载时机的原因
解决方案是去实现ApplicationContextAware这个手动获取bean,
@Component
public class SpringBeanUtilFactory implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringBeanUtilFactory .applicationContext=applicationContext;
}
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
/**
* 从当前IOC获取bean
* @param clazz
*/
public static <T> T getObject(Class<T> clazz){
return applicationContext.getBean(clazz);
}
}
然后在监听器使用
```SpringBeanUtilFactory.getObject(xxx.class)
示例如下:
WfFormMapper form= SpringJobBeanFactory.getObject(WfFormMapper.class);
这样就获取到了WfFormMapper 的bean可以做数据库的crud操作了