Camunda是从2013年fork Activiti5.11得来,并做了大量优化,推荐使用Camunda,下面将对比这两个的监听实现。
1、camunda 7.0.0-alpha1于2013年3月14日发布;
2、camunda 7.0.0-Final于2013年8月29日发布,提供ProcessApplicationEventListenerPlugin 内置插件实现全局监听;
3、activiti-5.11于2012年12月5日发布;
4、activiti-5.15于2014年3月21日发布,提供ActivitiEventListener接口,由业务实现全局监听;
Spring Boot 下 Activit5配置全局监听实现:
@Component
public class MyEventListener implements ActivitiEventListener {
@Override
public void onEvent(ActivitiEvent event) {
switch (event.getType()) {
case JOB_EXECUTION_SUCCESS:
System.out.println("A job well done!");
break;
case JOB_EXECUTION_FAILURE:
System.out.println("A job has failed...");
break;
default:
System.out.println("Event received: " + event.getType());
}
}
@Override
public boolean isFailOnException() {
// The logic in the onEvent method of this listener is not critical, exceptions
// can be ignored if logging fails...
return false;
}
}
Activiti配置类:
@Component
public class ActivitiConfig implements ProcessEngineConfigurationConfigurer {
@Autowired
private MyEventListener myEventListener;
@Override
public void configure(SpringProcessEngineConfiguration processEngineConfiguration) {
List<ActivitiEventListener> activitiEventListener=new ArrayList<ActivitiEventListener>();
activitiEventListener.add(myEventListener);//配置全局监听器
processEngineConfiguration.setEventListeners(activitiEventListener);
}
}
Spring Boot 下Camunda全局监听实现:
/**
**流程全局事件注入插件
***
**/
@Component
public class CamundaGlobalListenerPlugin extends AbstractProcessEnginePlugin{
@Override
public void preInit(ProcessEngineConfigurationImpl processEngineConfiguration) {
List<BpmnParseListener> preParseListeners = processEngineConfiguration.getCustomPreBPMNParseListeners();
if(preParseListeners == null) {
preParseListeners = new ArrayList<BpmnParseListener>();
processEngineConfiguration.setCustomPreBPMNParseListeners(preParseListeners);
}
preParseListeners.add(new CamundaGlobalListener());
}
}
/**
**流程全局事件监听注入
***
**/
public class CamundaGlobalListener extends AbstractBpmnParseListener {
public final static ExecutionListener EXECUTION_LISTENER = new CamundaGlobalListenerDelegate();
public final static TaskListener TASK_LISTENER = new CamundaGlobalListenerDelegate();
protected void addEndEventListener(ScopeImpl activity) {
//activity.addExecutionListener(ExecutionListener.EVENTNAME_END, EXECUTION_LISTENER);
activity.addListener(ExecutionListener.EVENTNAME_END, EXECUTION_LISTENER);
}
protected void addStartEventListener(ScopeImpl activity) {
//activity.addExecutionListener(ExecutionListener.EVENTNAME_START, EXECUTION_LISTENER);
activity.addListener(ExecutionListener.EVENTNAME_START, EXECUTION_LISTENER);
}
protected void addTakeEventListener(TransitionImpl transition) {
//transition.addExecutionListener(EXECUTION_LISTENER);
transition.addListener(ExecutionListener.EVENTNAME_TAKE, EXECUTION_LISTENER);
}
protected void addTaskAssignmentListeners(TaskDefinition taskDefinition) {
taskDefinition.addTaskListener(TaskListener.EVENTNAME_ASSIGNMENT, TASK_LISTENER);
}
protected void addTaskCreateListeners(TaskDefinition taskDefinition) {
taskDefinition.addTaskListener(TaskListener.EVENTNAME_CREATE, TASK_LISTENER);
}
protected void addTaskCompleteListeners(TaskDefinition taskDefinition) {
taskDefinition.addTaskListener(TaskListener.EVENTNAME_COMPLETE, TASK_LISTENER);
}
protected void addTaskUpdateListeners(TaskDefinition taskDefinition) {
taskDefinition.addTaskListener(TaskListener.EVENTNAME_UPDATE, TASK_LISTENER);
}
protected void addTaskDeleteListeners(TaskDefinition taskDefinition) {
taskDefinition.addTaskListener(TaskListener.EVENTNAME_DELETE, TASK_LISTENER);
}
// BpmnParseListener implementation
// /
@Override
public void parseProcess(Element processElement, ProcessDefinitionEntity processDefinition) {
addStartEventListener(processDefinition);
addEndEventListener(processDefinition);
}
@Override
public void parseStartEvent(Element startEventElement, ScopeImpl scope, ActivityImpl startEventActivity) {
addStartEventListener(startEventActivity);
addEndEventListener(startEventActivity);
}
@Override
public void parseExclusiveGateway(Element exclusiveGwElement, ScopeImpl scope, ActivityImpl activity) {
addStartEventListener(activity);
addEndEventListener(activity);
}
@Override
public void parseInclusiveGateway(Element inclusiveGwElement, ScopeImpl scope, ActivityImpl activity) {
addStartEventListener(activity);
addEndEventListener(activity);
}
@Override
public void parseParallelGateway(Element parallelGwElement, ScopeImpl scope, ActivityImpl activity) {
addStartEventListener(activity);
addEndEventListener(activity);
}
@Override
public void parseScriptTask(Element scriptTaskElement, ScopeImpl scope, ActivityImpl activity) {
addStartEventListener(activity);
addEndEventListener(activity);
}
@Override
public void parseServiceTask(Element serviceTaskElement, ScopeImpl scope, ActivityImpl activity) {
addStartEventListener(activity);
addEndEventListener(activity);
}
@Override
public void parseBusinessRuleTask(Element businessRuleTaskElement, ScopeImpl scope, ActivityImpl activity) {
addStartEventListener(activity);
addEndEventListener(activity);
}
@Override
public void parseTask(Element taskElement, ScopeImpl scope, ActivityImpl activity) {
addStartEventListener(activity);
addEndEventListener(activity);
}
@Override
public void parseManualTask(Element manualTaskElement, ScopeImpl scope, ActivityImpl activity) {
addStartEventListener(activity);
addEndEventListener(activity);
}
@Override
public void parseUserTask(Element userTaskElement, ScopeImpl scope, ActivityImpl activity) {
addStartEventListener(activity);
addEndEventListener(activity);
UserTaskActivityBehavior activityBehavior = (UserTaskActivityBehavior) activity.getActivityBehavior();
TaskDefinition taskDefinition = activityBehavior.getTaskDefinition();
addTaskCreateListeners(taskDefinition);
addTaskAssignmentListeners(taskDefinition);
addTaskCompleteListeners(taskDefinition);
addTaskUpdateListeners(taskDefinition);
addTaskDeleteListeners(taskDefinition);
}
@Override
public void parseEndEvent(Element endEventElement, ScopeImpl scope, ActivityImpl activity) {
addStartEventListener(activity);
addEndEventListener(activity);
}
@Override
public void parseBoundaryTimerEventDefinition(Element timerEventDefinition, boolean interrupting,
ActivityImpl timerActivity) {
// start and end event listener are set by parseBoundaryEvent()
}
@Override
public void parseBoundaryErrorEventDefinition(Element errorEventDefinition, boolean interrupting,
ActivityImpl activity, ActivityImpl nestedErrorEventActivity) {
// start and end event listener are set by parseBoundaryEvent()
}
@Override
public void parseSubProcess(Element subProcessElement, ScopeImpl scope, ActivityImpl activity) {
addStartEventListener(activity);
addEndEventListener(activity);
}
@Override
public void parseCallActivity(Element callActivityElement, ScopeImpl scope, ActivityImpl activity) {
addStartEventListener(activity);
addEndEventListener(activity);
}
@Override
public void parseProperty(Element propertyElement, VariableDeclaration variableDeclaration, ActivityImpl activity) {
}
@Override
public void parseSequenceFlow(Element sequenceFlowElement, ScopeImpl scopeElement, TransitionImpl transition) {
addTakeEventListener(transition);
}
@Override
public void parseSendTask(Element sendTaskElement, ScopeImpl scope, ActivityImpl activity) {
addStartEventListener(activity);
addEndEventListener(activity);
}
@Override
public void parseMultiInstanceLoopCharacteristics(Element activityElement,
Element multiInstanceLoopCharacteristicsElement, ActivityImpl activity) {
addStartEventListener(activity);
addEndEventListener(activity);
}
@Override
public void parseRootElement(Element rootElement, List<ProcessDefinitionEntity> processDefinitions) {
}
@Override
public void parseIntermediateTimerEventDefinition(Element timerEventDefinition, ActivityImpl timerActivity) {
// start and end event listener are set by parseIntermediateCatchEvent()
}
@Override
public void parseReceiveTask(Element receiveTaskElement, ScopeImpl scope, ActivityImpl activity) {
addStartEventListener(activity);
addEndEventListener(activity);
}
@Override
public void parseIntermediateSignalCatchEventDefinition(Element signalEventDefinition,
ActivityImpl signalActivity) {
// start and end event listener are set by parseIntermediateCatchEvent()
}
@Override
public void parseBoundarySignalEventDefinition(Element signalEventDefinition, boolean interrupting,
ActivityImpl signalActivity) {
// start and end event listener are set by parseBoundaryEvent()
}
@Override
public void parseEventBasedGateway(Element eventBasedGwElement, ScopeImpl scope, ActivityImpl activity) {
addStartEventListener(activity);
addEndEventListener(activity);
}
@Override
public void parseTransaction(Element transactionElement, ScopeImpl scope, ActivityImpl activity) {
addStartEventListener(activity);
addEndEventListener(activity);
}
@Override
public void parseCompensateEventDefinition(Element compensateEventDefinition, ActivityImpl compensationActivity) {
}
@Override
public void parseIntermediateThrowEvent(Element intermediateEventElement, ScopeImpl scope, ActivityImpl activity) {
addStartEventListener(activity);
addEndEventListener(activity);
}
@Override
public void parseIntermediateCatchEvent(Element intermediateEventElement, ScopeImpl scope, ActivityImpl activity) {
addStartEventListener(activity);
addEndEventListener(activity);
}
@Override
public void parseBoundaryEvent(Element boundaryEventElement, ScopeImpl scopeElement, ActivityImpl activity) {
addStartEventListener(activity);
addEndEventListener(activity);
}
@Override
public void parseIntermediateMessageCatchEventDefinition(Element messageEventDefinition,
ActivityImpl nestedActivity) {
}
@Override
public void parseBoundaryMessageEventDefinition(Element element, boolean interrupting,
ActivityImpl messageActivity) {
}
@Override
public void parseBoundaryEscalationEventDefinition(Element escalationEventDefinition, boolean interrupting,
ActivityImpl boundaryEventActivity) {
}
@Override
public void parseBoundaryConditionalEventDefinition(Element element, boolean interrupting,
ActivityImpl conditionalActivity) {
}
@Override
public void parseIntermediateConditionalEventDefinition(Element conditionalEventDefinition,
ActivityImpl conditionalActivity) {
}
public void parseConditionalStartEventForEventSubprocess(Element element, ActivityImpl conditionalActivity,
boolean interrupting) {
}
}
Camunda全局业务事件处理器:
/**
**流程全局事件处理器
***
**/
public class CamundaGlobalListenerDelegate implements ExecutionListener, TaskListener {
private static final Logger logger = LoggerFactory.getLogger(CamundaGlobalListenerDelegate.class);
@Override
public void notify(DelegateTask delegateTask) {
logger.info("delegateTask------------------> " + delegateTask.getName()+"----------->"+delegateTask.getEventName()+"----->"+
delegateTask.getBpmnModelElementInstance().getElementType().getTypeName()+"--->"+JSON.toJSONString(((TaskEntity)delegateTask).getPersistentState(),SerializerFeature.DisableCircularReferenceDetect));
}
@Override
public void notify(DelegateExecution execution) throws Exception {
logger.info("execution------------------> " + execution.getCurrentActivityName()+"----------->"+execution.getEventName()+"----->"+
execution.getBpmnModelElementInstance().getElementType().getTypeName()+"---->"+JSON.toJSONString(((ExecutionEntity)execution).getPersistentState(),SerializerFeature.DisableCircularReferenceDetect));
}
}
另:Spring Boot下,在application.yml可通过Spring Eventing Bridge简单方式开启监听,配置如下:
camunda.bpm.eventing.execution=true
camunda.bpm.eventing.history=true
camunda.bpm.eventing.task=true
然后再添加一个类即可
import org.camunda.bpm.engine.delegate.DelegateExecution;
import org.camunda.bpm.engine.delegate.DelegateTask;
import org.camunda.bpm.engine.impl.history.event.HistoryEvent;
import org.springframework.context.event.EventListener;
import org.springframework.stereotype.Component;
@Component
class MyListener {
@EventListener
public void onTaskEvent(DelegateTask taskDelegate) {
// handle mutable task event
}
@EventListener
public void onTaskEvent(TaskEvent taskEvent) {
// handle immutable task event
}
@EventListener
public void onExecutionEvent(DelegateExecution executionDelegate) {
// handle mutable execution event
}
@EventListener
public void onExecutionEvent(ExecutionEvent executionEvent) {
// handle immutable execution event
}
@EventListener
public void onHistoryEvent(HistoryEvent historyEvent) {
// handle history event
}
}