为什么这么写
activiti || flowable 可以通过 在流程图上定义监听事件来实现事件监听
如 节点创建事件监听器
<userTask activiti:candidateGroups="A001B002C003D750" activiti:exclusive="true" id="_36" name="测试1">
<extensionElements>
<activiti:taskListener delegateExpression="${preHandleEndTaskListener}" event="create"/>
如 节点结束事件监听器
<userTask activiti:exclusive="true" id="_7" name="测试2">
<extensionElements>
<activiti:taskListener delegateExpression="${faultClosedLoopSetGroup}" event="complete"/>
delegateExpression 里面定义的就是spring中的bean名,这样即可实现节点的事件监听功能
弊端:需要反复的修改bpmn文件,会多次发布更新流程图
如何实现只写代码即可添加事件监听
通过 activiti || flowable 提供的事件监听器来实现
下面的代码是基于flowable来实现的,基于activiti 代码基本一致,只是相关的类名得有 Flowable 开头的变成 Activiti 开头
如 FlowableEventListener》ActivitiEventListener
处理接口定义
public interface FlowEventHandler {
default void handleProcess(String processId){ };
default void handleTask(TaskEntity taskEntity){ };
}
注解定义
@Target({ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface FlowEventAnno
{
/**
* 流程定义
*/
public String processDef() ;
/**
* 节点定义
*/
public String taskDef() default "";
/**
* 事件类型
*/
public FlowableEngineEventType eventType();
}
策略类
@Component
public class FlowEventStrategy implements BeanPostProcessor {
private Map<FlowableEngineEventType,Map<String, Set<FlowEventHandler>>> processEventMap = new HashMap<>();
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof FlowEventHandler){
FlowEventAnno annotation = bean.getClass().getAnnotation(FlowEventAnno.class);
if (null != annotation){
// 处理类归类
FlowableEngineEventType flowableEngineEventType = annotation.eventType();
if (!processEventMap.containsKey(flowableEngineEventType)){
processEventMap.put(flowableEngineEventType,new HashMap<>());
}
String processDef = annotation.processDef();
String taskDef = annotation.taskDef();
Map<String, Set<FlowEventHandler>> stringListMap = processEventMap.get(flowableEngineEventType);
if (!stringListMap.containsKey(processDef)){
// 流程类处理策略不需要给定 节点def
if (flowableEngineEventType.equals(FlowableEngineEventType.PROCESS_COMPLETED) ||
flowableEngineEventType.equals(FlowableEngineEventType.PROCESS_STARTED)){
stringListMap.put(getKey(processDef,""),new HashSet<>());
}
// 节点类处理策略必须要给定 节点def
else if (flowableEngineEventType.equals(FlowableEngineEventType.TASK_COMPLETED) ||
flowableEngineEventType.equals(FlowableEngineEventType.TASK_CREATED)){
// todo 可通过查询数据库进行 processDef 和 taskDef 的对应性 校验,这样出错概率更小
if (StringUtils.isEmpty(taskDef)){
throw new RuntimeException("flow节点处理类注解定义有误,类:" + bean.getClass().getName());
}
stringListMap.put(getKey(processDef,taskDef),new HashSet<>());
}
}
// 保存
stringListMap.get(getKey(processDef,taskDef)).add((FlowEventHandler) bean);
}
}
return bean;
}
private String getKey(String processDef,String taskDef){
return processDef + "_" + taskDef;
}
public Set<FlowEventHandler> getHanlders(FlowableEngineEventType flowableEngineEventType,String processDef,String taskDef){
if (!processEventMap.containsKey(flowableEngineEventType)){
return new HashSet<>();
}
Map<String, Set<FlowEventHandler>> stringListMap = processEventMap.get(flowableEngineEventType);
if (!stringListMap.containsKey(getKey(processDef,taskDef))){
return new HashSet<>();
}
return stringListMap.get(getKey(processDef,taskDef));
}
/**
* 增加 流程处理类
* @param flowableEngineEventType
* @param processDef
* @param flowEventHandler
*/
public void addProcessHandler(FlowableEngineEventType flowableEngineEventType,String processDef,FlowEventHandler flowEventHandler){
addTaskHandler(flowableEngineEventType,processDef,"",flowEventHandler);
}
/**
* 增加 任务 处理类
* @param flowableEngineEventType
* @param processDef
* @param taskDef
* @param flowEventHandler
*/
public void addTaskHandler(FlowableEngineEventType flowableEngineEventType,String processDef,String taskDef,FlowEventHandler flowEventHandler){
if (!processEventMap.containsKey(flowableEngineEventType)){
processEventMap.put(flowableEngineEventType,new HashMap<>());
}
Map<String, Set<FlowEventHandler>> stringListMap = processEventMap.get(flowableEngineEventType);
if (!stringListMap.containsKey(getKey(processDef,taskDef))){
stringListMap.put(getKey(processDef,taskDef),new HashSet<>());
}
// 保存
stringListMap.get(getKey(processDef,taskDef)).add(flowEventHandler);
}
}
实现类-流程监听
@Component
@FlowEventAnno(eventType = FlowableEngineEventType.PROCESS_STARTED, processDef = "process_ff53f4gf")
public class RemoveAndBuildCreateListener implements FlowEventHandler {
@Override
public void handleProcess(String processId) {
System.out.println(processId);
}
}
实现类-节点监听
@Component
@FlowEventAnno(eventType = FlowableEngineEventType.TASK_CREATED, processDef = "process_ff53f4gf",taskDef = "Activity_1a3jyl5")
public class RemoveAndBuildTaskCreateListener implements FlowEventHandler {
@Override
public void handleTask(TaskEntity taskEntity) {
System.out.println(taskEntity.getVariableInstances());
}
}
定义监听器
流程定义id 和 事件类型,找到对应的策略处理类,来执行响应的逻辑
@Component
public class ProcessEventListener implements FlowableEventListener {
@Autowired
private FlowEventStrategy flowEventStrategy;
@Override
public void onEvent(FlowableEvent flowableEvent) {
// 流程开始 || 流程结束
if (flowableEvent.getType().equals(PROCESS_STARTED) || flowableEvent.getType().equals(PROCESS_COMPLETED)){
FlowableProcessStartedEventImpl impl = (FlowableProcessStartedEventImpl) flowableEvent;
String processInstanceId = impl.getProcessInstanceId();
String defId = impl.getProcessDefinitionId().split(":")[0];
// 根据流程定义id 和 事件类型,找到对应的处理类
Set<FlowEventHandler> hanlders = flowEventStrategy.getHanlders((FlowableEngineEventType) flowableEvent.getType(), defId, "");
for (FlowEventHandler hanlder : hanlders) {
hanlder.handleProcess(processInstanceId);
}
}
// 节点开始 || 节点结束
else if (flowableEvent.getType().equals(TASK_CREATED) || flowableEvent.getType().equals(TASK_COMPLETED)){
TaskEntity entity = (TaskEntity) (((FlowableEntityEventImpl) flowableEvent).getEntity());
String taskDefinitionKey = entity.getTaskDefinitionKey();
String processDefId = entity.getProcessDefinitionId().split(":")[0];
// 根据流程定义id 和 事件类型,找到对应的处理类
Set<FlowEventHandler> hanlders = flowEventStrategy.getHanlders((FlowableEngineEventType) flowableEvent.getType(), processDefId, taskDefinitionKey);
for (FlowEventHandler hanlder : hanlders) {
hanlder.handleTask(entity);
}
}
}
}
配置监听器
@Configuration
public class ProjectFlowableConfig {
@Autowired
private ProcessEventListener processEventListener;
@Bean
public BeanPostProcessor activitiConfigurer() {
return new BeanPostProcessor() {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof SpringProcessEngineConfiguration) {
// 设置事件监听器
List<FlowableEventListener> listenerList = new ArrayList<>();
listenerList.add(processEventListener);
((SpringProcessEngineConfiguration) bean).getProcessEngineConfiguration().setEventListeners(listenerList);
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
};
}
}
实现效果
后面需要对某节点增加事件监听时,只需编写java代码即可