概述
在《activiti学习(六)——从bpmn文件转化为bpmnModel的过程》提到过,activiti会把bpmn图中的元素转化到bpmnModel中,然后再通过对象解析器,把各元素解析为流程虚拟机识别的对象。本章主要讲解这个解析过程。
activiti的元素非常多,这里我们仅介绍一下process及内部userTask、sequenceFlow的解析,其他元素请自行研究。简单来讲,流程虚拟机会把流程中的活动如userTask、startEvent等解析为ActivityImpl对象,把连线解析为TransitionImpl对象,并为他们设置对应的行为。当流程执行到某个对象时,就会执行该对象对应的行为。
对象解析器的初始化
首先看看activiti内置的对象解析器,在ProcessEngineConfigurationImpl.java:
protected void init() {
//......省略
initServices();
initIdGenerator();
initDeployers();
initJobHandlers();
initJobExecutor();
//......省略
}
protected void initDeployers() {
if (this.deployers==null) {
this.deployers = new ArrayList<Deployer>();
if (customPreDeployers!=null) {
this.deployers.addAll(customPreDeployers);
}
this.deployers.addAll(getDefaultDeployers());
if (customPostDeployers!=null) {
this.deployers.addAll(customPostDeployers);
}
}
//......省略
}
protected Collection< ? extends Deployer> getDefaultDeployers() {
//......省略
List<BpmnParseHandler> parseHandlers = new ArrayList<BpmnParseHandler>();
if(getPreBpmnParseHandlers() != null) {
parseHandlers.addAll(getPreBpmnParseHandlers());
}
parseHandlers.addAll(getDefaultBpmnParseHandlers());
if(getPostBpmnParseHandlers() != null) {
parseHandlers.addAll(getPostBpmnParseHandlers());
}
BpmnParseHandlers bpmnParseHandlers = new BpmnParseHandlers();
bpmnParseHandlers.addHandlers(parseHandlers);
bpmnParser.setBpmnParserHandlers(bpmnParseHandlers);
bpmnDeployer.setBpmnParser(bpmnParser);
defaultDeployers.add(bpmnDeployer);
return defaultDeployers;
}
protected List<BpmnParseHandler> getDefaultBpmnParseHandlers() {
List<BpmnParseHandler> bpmnParserHandlers = new ArrayList<BpmnParseHandler>();
bpmnParserHandlers.add(new BoundaryEventParseHandler());
bpmnParserHandlers.add(new BusinessRuleParseHandler());
bpmnParserHandlers.add(new CallActivityParseHandler());
bpmnParserHandlers.add(new CancelEventDefinitionParseHandler());
bpmnParserHandlers.add(new CompensateEventDefinitionParseHandler());
bpmnParserHandlers.add(new EndEventParseHandler());
bpmnParserHandlers.add(new ErrorEventDefinitionParseHandler());
bpmnParserHandlers.add(new EventBasedGatewayParseHandler());
bpmnParserHandlers.add(new ExclusiveGatewayParseHandler());
bpmnParserHandlers.add(new InclusiveGatewayParseHandler());
bpmnParserHandlers.add(new IntermediateCatchEventParseHandler());
bpmnParserHandlers.add(new IntermediateThrowEventParseHandler());
bpmnParserHandlers.add(new ManualTaskParseHandler());
bpmnParserHandlers.add(new MessageEventDefinitionParseHandler());
bpmnParserHandlers.add(new ParallelGatewayParseHandler());
bpmnParserHandlers.add(new ProcessParseHandler());
bpmnParserHandlers.add(new ReceiveTaskParseHandler());
bpmnParserHandlers.add(new ScriptTaskParseHandler());
bpmnParserHandlers.add(new SendTaskParseHandler());
bpmnParserHandlers.add(new SequenceFlowParseHandler());
bpmnParserHandlers.add(new ServiceTaskParseHandler());
bpmnParserHandlers.add(new SignalEventDefinitionParseHandler());
bpmnParserHandlers.add(new StartEventParseHandler());
bpmnParserHandlers.add(new SubProcessParseHandler());
bpmnParserHandlers.add(new EventSubProcessParseHandler());
bpmnParserHandlers.add(new TaskParseHandler());
bpmnParserHandlers.add(new TimerEventDefinitionParseHandler());
bpmnParserHandlers.add(new TransactionParseHandler());
bpmnParserHandlers.add(new UserTaskParseHandler());
if (customDefaultBpmnParseHandlers != null) {
//......省略
//自定义对象解析器,替换默认对象解析器
}
// History
for (BpmnParseHandler handler : getDefaultHistoryParseHandlers()) {
bpmnParserHandlers.add(handler);
}
return bpmnParserHandlers;
}
第5行初始化部署器,17行获取默认部署器,29-35行为添加自定义前置对象解析器、默认对象解析器和后置对象解析器。48-77行添加具体的默认对象解析器,79-82行用自定义对象解析器替换默认对象解析器,85-87行添加历史对象解析器。
在《activiti学习(六)》中,我们曾经追踪BpmnParse.java:
public BpmnParse execute() {
try {
ProcessEngineConfigurationImpl processEngineConfiguration = Context.getProcessEngineConfiguration();
BpmnXMLConverter converter = new BpmnXMLConverter();
boolean enableSafeBpmnXml = false;
String encoding = null;
if (processEngineConfiguration != null) {
enableSafeBpmnXml = processEngineConfiguration.isEnableSafeBpmnXml();
encoding = processEngineConfiguration.getXmlEncoding();
}
if (encoding != null) {
bpmnModel = converter.convertToBpmnModel(streamSource, validateSchema, enableSafeBpmnXml, encoding);
} else {
bpmnModel = converter.convertToBpmnModel(streamSource, validateSchema, enableSafeBpmnXml);
}
// XSD validation goes first, then process/semantic validation
if (validateProcess) {
......
//省略校验bpmnModel有效性
}
// Validation successfull (or no validation)
createImports();
createItemDefinitions();
createMessages();
createOperations();
transformProcessDefinitions();
} catch (Exception e) {
if (e instanceof ActivitiException) {
throw (ActivitiException) e;
} else if (e instanceof XMLException) {
throw (XMLException) e;
} else {
throw new ActivitiException("Error parsing XML", e);
}
}
return this;
}
protected void transformProcessDefinitions() {
sequenceFlows = new HashMap<String, TransitionImpl>();
for (Process process : bpmnModel.getProcesses()) {
if (process.isExecutable()) {
bpmnParserHandlers.parseElement(this, process);
}
}
if (!processDefinitions.isEmpty()) {
processDI();
}
}
31行transformProcessDefinitions()开始执行对象解析的转化。48-52行对bpmnModel中的每个设置了isExecutable="true"的process进行解析。调用BpmnParseHandlers.parseElement()方法,跟踪BpmnParseHandlers.java:
public void parseElement(BpmnParse bpmnParse, BaseElement element) {
if (element instanceof DataObject) {
// ignore DataObject elements because they are processed on Process and Sub process level
return;
}
if (element instanceof FlowElement) {
bpmnParse.setCurrentFlowElement((FlowElement) element);
}
// Execute parse handlers
List<BpmnParseHandler> handlers = parseHandlers.get(element.getClass());
if (handlers == null) {
LOGGER.warn("Could not find matching parse handler for + " + element.getId() + " this is likely a bug.");
} else {
for (BpmnParseHandler handler : handlers) {
handler.parse(bpmnParse, element);
}
}
}
13行获取元素对应的对象解析器。19行使用对象解析器解析元素
process解析
以下我们解析process为例,13行会获取ProcessParseHandler。接着19行handler.parse(bpmnParse, element)调用跳转到AbstractActivityBpmnParseHandler.java:
public void parse(BpmnParse bpmnParse, BaseElement element) {
super.parse(bpmnParse, element);
if (element instanceof Activity
&& ((Activity) element).getLoopCharacteristics() != null) {
createMultiInstanceLoopCharacteristics(bpmnParse, (Activity) element);
}
}
第2行调用父类的parse方法,跟踪AbstractFlowNodeBpmnParseHandler.java:
public void parse(BpmnParse bpmnParse, BaseElement element) {
super.parse(bpmnParse, element);
createExecutionListenersOnScope(bpmnParse, ((FlowNode) element).getExecutionListeners(), findActivity(bpmnParse, element.getId()));
}
第2行调用父类的parse方法,第3行创建执行监听器。跟踪AbstractBpmnParseHandler.java:
public void parse(BpmnParse bpmnParse, BaseElement element) {
T baseElement = (T) element;
executeParse(bpmnParse, baseElement);
}
上面第3行的executeParse方法根据多态,会调用内置process对象解析器ProcessParseHandler,跟踪ProcessParseHandler.java:
protected void executeParse(BpmnParse bpmnParse, Process process) {
if (process.isExecutable() == false) {
LOGGER.info("Ignoring non-executable process with id='" + process.getId() + "'. Set the attribute isExecutable=\"true\" to deploy this process.");
} else {
bpmnParse.getProcessDefinitions().add(transformProcess(bpmnParse, process));
}
}
protected ProcessDefinitionEntity transformProcess(BpmnParse bpmnParse, Process process) {
ProcessDefinitionEntity currentProcessDefinition = new ProcessDefinitionEntity();
bpmnParse.setCurrentProcessDefinition(currentProcessDefinition);
currentProcessDefinition.setKey(process.getId());
currentProcessDefinition.setName(process.getName());
currentProcessDefinition.setCategory(bpmnParse.getBpmnModel().getTargetNamespace());
currentProcessDefinition.setDescription(process.getDocumentation());
currentProcessDefinition.setProperty(PROPERTYNAME_DOCUMENTATION, process.getDocumentation()); // Kept for backwards compatibility. See ACT-1020
currentProcessDefinition.setTaskDefinitions(new HashMap<String, TaskDefinition>());
currentProcessDefinition.setDeploymentId(bpmnParse.getDeployment().getId());
createExecutionListenersOnScope(bpmnParse, process.getExecutionListeners(), currentProcessDefinition);
createEventListeners(bpmnParse, process.getEventListeners(), currentProcessDefinition);
ExpressionManager expressionManager = bpmnParse.getExpressionManager();
for (String candidateUser : process.getCandidateStarterUsers()) {
currentProcessDefinition.addCandidateStarterUserIdExpression(expressionManager.createExpression(candidateUser));
}
for (String candidateGroup : process.getCandidateStarterGroups()) {
currentProcessDefinition.addCandidateStarterGroupIdExpression(expressionManager.createExpression(candidateGroup));
}
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Parsing process {}", currentProcessDefinition.getKey());
}
bpmnParse.setCurrentScope(currentProcessDefinition);
bpmnParse.processFlowElements(process.getFlowElements());
processArtifacts(bpmnParse, process.getArtifacts(), currentProcessDefinition);
// parse out any data objects from the template in order to set up the necessary process variables
Map<String, Object> variables = processDataObjects(bpmnParse, process.getDataObjects(), currentProcessDefinition);
if (null != currentProcessDefinition.getVariables()) {
currentProcessDefinition.getVariables().putAll(variables);
} else {
currentProcessDefinition.setVariables(variables);
}
bpmnParse.removeCurrentScope();
if (process.getIoSpecification() != null) {
IOSpecification ioSpecification = createIOSpecification(bpmnParse, process.getIoSpecification());
currentProcessDefinition.setIoSpecification(ioSpecification);
}
return currentProcessDefinition;
}
第5行把transformProcess中解析出来的流程定义实体添加到bpmnParse的流程定义实体集合中。13-19行设置process的属性,20-21行创建对应的执行监听器和事件监听器。37行setCurrentScope把当前处理的流程定义压入栈中,处理子元素时,子元素可以通过getCurrentScope获取当前的ProcessDefinitionEntity。39行处理process下的子元素。
接下来跟踪bpmnParse.processFlowElements(process.getFlowElements()),查看BpmnParse.java:
public void processFlowElements(Collection<FlowElement> flowElements) {
List<SequenceFlow> sequenceFlowToParse = new ArrayList<SequenceFlow>();
List<BoundaryEvent> boundaryEventsToParse = new ArrayList<BoundaryEvent>();
List<FlowElement> defferedFlowElementsToParse = new ArrayList<FlowElement>();
for (FlowElement flowElement : flowElements) {
if (flowElement instanceof SequenceFlow) {
sequenceFlowToParse.add((SequenceFlow) flowElement);
} else if (flowElement instanceof BoundaryEvent) {
boundaryEventsToParse.add((BoundaryEvent) flowElement);
} else if (flowElement instanceof Event) {
defferedFlowElementsToParse.add(flowElement);
} else {
bpmnParserHandlers.parseElement(this, flowElement);
}
}
// Deferred elements
for (FlowElement flowElement : defferedFlowElementsToParse) {
bpmnParserHandlers.parseElement(this, flowElement);
}
// Boundary events are parsed after all the regular activities are parsed
for (BoundaryEvent boundaryEvent : boundaryEventsToParse) {
bpmnParserHandlers.parseElement(this, boundaryEvent);
}
// sequence flows
for (SequenceFlow sequenceFlow : sequenceFlowToParse) {
bpmnParserHandlers.parseElement(this, sequenceFlow);
}
}
7-12行分别把连线、边界事件、事件存起来,在18-28行处理。14行先处理其他元素(例如userTask)之后再处理它们。因为连线、事件这些和具体的活动相关,因此先实例化活动元素,然后实例化连线、事件元素时,再把它们和活动关联起来。
userTask解析
接下来我们分别看userTask对象解析器。解析process子元素的bpmnParserHandlers.parseElement与前面解析process调用情况类似,仅在AbstractBpmnParseHandler.java时根据多态会调用UserTaskParseHandle。我们先看UserTaskParseHandler.java
protected void executeParse(BpmnParse bpmnParse, UserTask userTask) {
ActivityImpl activity = createActivityOnCurrentScope(bpmnParse, userTask, BpmnXMLConstants.ELEMENT_TASK_USER);
activity.setAsync(userTask.isAsynchronous());
activity.setExclusive(!userTask.isNotExclusive());
TaskDefinition taskDefinition = parseTaskDefinition(bpmnParse, userTask, userTask.getId(), (ProcessDefinitionEntity) bpmnParse.getCurrentScope().getProcessDefinition());
activity.setProperty(PROPERTY_TASK_DEFINITION, taskDefinition);
activity.setActivityBehavior(bpmnParse.getActivityBehaviorFactory().createUserTaskActivityBehavior(userTask, taskDefinition));
}
第2行为userTask创建ActivitiImpl,第7行为userTask创建任务定义,第9行为userTask设置行为。我们跟踪createActivityOnCurrentScope看其如何创建ActivitiImpl。查看AbstractBpmnParseHandler.java:
public ActivityImpl createActivityOnCurrentScope(BpmnParse bpmnParse, FlowElement flowElement, String xmlLocalName) {
return createActivityOnScope(bpmnParse, flowElement, xmlLocalName, bpmnParse.getCurrentScope());
}
public ActivityImpl createActivityOnScope(BpmnParse bpmnParse, FlowElement flowElement, String xmlLocalName, ScopeImpl scopeElement) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Parsing activity {}", flowElement.getId());
}
ActivityImpl activity = scopeElement.createActivity(flowElement.getId());
bpmnParse.setCurrentActivity(activity);
activity.setProperty("name", flowElement.getName());
activity.setProperty("documentation", flowElement.getDocumentation());
if (flowElement instanceof Activity) {
Activity modelActivity = (Activity) flowElement;
activity.setProperty("default", modelActivity.getDefaultFlow());
if(modelActivity.isForCompensation()) {
activity.setProperty(PROPERTYNAME_IS_FOR_COMPENSATION, true);
}
} else if (flowElement instanceof Gateway) {
activity.setProperty("default", ((Gateway) flowElement).getDefaultFlow());
}
activity.setProperty("type", xmlLocalName);
return activity;
}
第10行创建ActivityImpl,15-23行判断如果属于活动对象或网关对象,对应不同的属性设置。这里的scopeElement就是userTask所在的ProcessDefinitionEntity,跟踪scopeElement.createActivity,查看ScopeImpl.java:
public ActivityImpl createActivity(String activityId) {
ActivityImpl activity = new ActivityImpl(activityId, processDefinition);
if (activityId!=null) {
if (processDefinition.findActivity(activityId) != null) {
throw new PvmException("duplicate activity id '" + activityId + "'");
}
namedActivities.put(activityId, activity);
}
activity.setParent(this);
activities.add(activity);
return activity;
}
第2行新建ActivityImpl对象,4-6行判断是否有重复命名。第10行添加到所属process的activities列表中
SequenceFlow解析
接下来看看连线的解析,SequenceFlowParseHandler.java:
protected void executeParse(BpmnParse bpmnParse, SequenceFlow sequenceFlow) {
ScopeImpl scope = bpmnParse.getCurrentScope();
ActivityImpl sourceActivity = scope.findActivity(sequenceFlow.getSourceRef());
ActivityImpl destinationActivity = scope.findActivity(sequenceFlow.getTargetRef());
Expression skipExpression;
if (StringUtils.isNotEmpty(sequenceFlow.getSkipExpression())) {
ExpressionManager expressionManager = bpmnParse.getExpressionManager();
skipExpression = expressionManager.createExpression(sequenceFlow.getSkipExpression());
} else {
skipExpression = null;
}
TransitionImpl transition = sourceActivity.createOutgoingTransition(sequenceFlow.getId(), skipExpression);
bpmnParse.getSequenceFlows().put(sequenceFlow.getId(), transition);
transition.setProperty("name", sequenceFlow.getName());
transition.setProperty("documentation", sequenceFlow.getDocumentation());
transition.setDestination(destinationActivity);
if (StringUtils.isNotEmpty(sequenceFlow.getConditionExpression())) {
Condition expressionCondition = new UelExpressionCondition(sequenceFlow.getConditionExpression());
transition.setProperty(PROPERTYNAME_CONDITION_TEXT, sequenceFlow.getConditionExpression());
transition.setProperty(PROPERTYNAME_CONDITION, expressionCondition);
}
createExecutionListenersOnTransition(bpmnParse, sequenceFlow.getExecutionListeners(), transition);
}
4-5行获取连线的首尾两个节点,7-13行为设置跳过表达式,15行通过起始节点创建TransitionImpl,21-25行设置条件表达式,27行设置执行监听器。表达式相关的内容后面的文章再进行分析。
小结
通过对process、userTask、sequenceFlow的解析,我们可以归纳,首先解析process,得到ProcessDefinitionEntity,然后把userTask等活动解析成ActivityImpl加入到ProcessDefinitionEntity中,再解析sequenceFlow为TransitionImpl,与各ActivityImpl关联起来,形成流程虚拟机运转的基础。