服务热线
135-6963-3175
我们的bpmn xml文件是如何通过引擎进行部署的呢?
文章概要: 1.bpmnParser解析器与解析处理器的初始化(关联bpmnParse工厂(核心)) 2.deploymentManager部署管理器的初始化与bpmnParser解析器的关联 3.仓库服务进行部署的调用(通过deploymentManager)
1、bpmn解析器及解析处理器的初始化
我们首先看
ProcessEngineConfigurationImpl的init方法里initBpmnParser()方法:
public void initBpmnParser() { if (bpmnParser == null) { bpmnParser = new BpmnParser(); } if (bpmnParseFactory == null) { bpmnParseFactory = new DefaultBpmnParseFactory();//该工厂用于创建bpmnParse } bpmnParser.setBpmnParseFactory(bpmnParseFactory);//解析工厂 bpmnParser.setActivityBehaviorFactory(activityBehaviorFactory);//行为工厂 bpmnParser.setListenerFactory(listenerFactory);//监听器工厂 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); }
上面方法对bpmParser解析器进行了初始化及用到的相关工厂(bpmnParse解析工厂用于创建bpmnParse解析器(核心,用于xml convertToBpmnModel解析转换的调用和行为的设置),行为类工厂用于创建行为,监听器工厂用于创建监听器)和一系列解析处理器(其实解析处理器用于设置元素行为,后面会分析)。
分前置、默认和后置处理器(后置主要用于加入适配activti5的解析处理器),主要来看activti提供的默认的解析处理器有哪些:
public List<BpmnParseHandler> getDefaultBpmnParseHandlers() { // Alphabetic list of default parse handler classes 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 AdhocSubProcessParseHandler());//特殊子流程解析处理器 bpmnParserHandlers.add(new TaskParseHandler());//任务解析处理器 bpmnParserHandlers.add(new TimerEventDefinitionParseHandler());//定时事件定义解析处理器 bpmnParserHandlers.add(new TransactionParseHandler());//事务解析处理器 bpmnParserHandlers.add(new UserTaskParseHandler());//用户任务解析处理器 // Replace any default handler if the user wants to replace them if (customDefaultBpmnParseHandlers != null) {//自定义的解析器 Map<Class<?>, BpmnParseHandler> customParseHandlerMap = new HashMap<Class<?>, BpmnParseHandler>(); for (BpmnParseHandler bpmnParseHandler : customDefaultBpmnParseHandlers) { for (Class<?> handledType : bpmnParseHandler.getHandledTypes()) { customParseHandlerMap.put(handledType, bpmnParseHandler); } } for (int i = 0; i < bpmnParserHandlers.size(); i++) { // All the default handlers support only one type BpmnParseHandler defaultBpmnParseHandler = bpmnParserHandlers.get(i); if (defaultBpmnParseHandler.getHandledTypes().size() != 1) { StringBuilder supportedTypes = new StringBuilder(); for (Class<?> type : defaultBpmnParseHandler.getHandledTypes()) { supportedTypes.append(" ").append(type.getCanonicalName()).append(" "); } throw new ActivitiException("The default BPMN parse handlers should only support one type, but " + defaultBpmnParseHandler.getClass() + " supports " + supportedTypes.toString() + ". This is likely a programmatic error"); } else { Class<?> handledType = defaultBpmnParseHandler.getHandledTypes().iterator().next(); if (customParseHandlerMap.containsKey(handledType)) {//自定义是否覆盖了默认的,若覆盖了则用自定义的 BpmnParseHandler newBpmnParseHandler = customParseHandlerMap.get(handledType); log.info("Replacing default BpmnParseHandler " + defaultBpmnParseHandler.getClass().getName() + " with " + newBpmnParseHandler.getClass().getName()); bpmnParserHandlers.set(i, newBpmnParseHandler); } } } } return bpmnParserHandlers; }
我们查看两个处理器源码:
public class ParallelGatewayParseHandler extends AbstractActivityBpmnParseHandler<ParallelGateway> { public Class<? extends BaseElement> getHandledType() { return ParallelGateway.class; } protected void executeParse(BpmnParse bpmnParse, ParallelGateway gateway) { gateway.setBehavior(bpmnParse.getActivityBehaviorFactory().createParallelGatewayActivityBehavior(gateway)); } } public class UserTaskParseHandler extends AbstractActivityBpmnParseHandler<UserTask> { public Class<? extends BaseElement> getHandledType() { return UserTask.class; } @Override protected void executeParse(BpmnParse bpmnParse, UserTask userTask) { userTask.setBehavior(bpmnParse.getActivityBehaviorFactory().createUserTaskActivityBehavior(userTask)); } } 查看父类: public abstract class AbstractActivityBpmnParseHandler<T extends FlowNode> extends AbstractFlowNodeBpmnParseHandler<T> { @Override public void parse(BpmnParse bpmnParse, BaseElement element) { super.parse(bpmnParse, element); if (element instanceof Activity && ((Activity) element).getLoopCharacteristics() != null) { createMultiInstanceLoopCharacteristics(bpmnParse, (Activity) element);//多实例 } } .... } 继续看父类: public abstract class AbstractFlowNodeBpmnParseHandler<T extends FlowNode> extends AbstractBpmnParseHandler<T> { //该类为空 } 继续看父类: public abstract class AbstractBpmnParseHandler<T extends BaseElement> implements BpmnParseHandler { private static final Logger logger = LoggerFactory.getLogger(AbstractBpmnParseHandler.class); public static final String PROPERTYNAME_EVENT_SUBSCRIPTION_DECLARATION = "eventDefinitions"; public static final String PROPERTYNAME_ERROR_EVENT_DEFINITIONS = "errorEventDefinitions"; public static final String PROPERTYNAME_TIMER_DECLARATION = "timerDeclarations"; public Set<Class<? extends BaseElement>> getHandledTypes() { Set<Class<? extends BaseElement>> types = new HashSet<Class<? extends BaseElement>>(); types.add(getHandledType()); return types; } protected abstract Class<? extends BaseElement> getHandledType(); @SuppressWarnings("unchecked") public void parse(BpmnParse bpmnParse, BaseElement element) { T baseElement = (T) element; executeParse(bpmnParse, baseElement); } protected abstract void executeParse(BpmnParse bpmnParse, T element); ....//省略 }
可以看出顶级父类是用了设计模式之模版方法模式定义了抽象方法executeParse用于获取并设置其行为类,
发现处理器主要是用于给元素节点设置行为类。
先给出bpmn解析处理器最终调用路径为BpmnParse->execute()->bpmnParser.getBpmnParserHandlers(i).parseElement()。
后续我们会进行逐步讲解。
2、部署管理器的初始化与解析器的关联
有了解析器之后,那么在何时调用呢?我们可看到在init方法里还有一个初始化方法:
initDeployers();//部署相关工厂帮助类的初始化创建
看部署管理器相关的处理化源码:
public 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); } } //部署管理器初始化 if (deploymentManager == null) { deploymentManager = new DeploymentManager(); deploymentManager.setDeployers(deployers); deploymentManager.setProcessDefinitionCache(processDefinitionCache);//流程定义缓存 deploymentManager.setProcessDefinitionInfoCache(processDefinitionInfoCache);//流程定义信息缓存 deploymentManager.setKnowledgeBaseCache(knowledgeBaseCache);//基础缓存 deploymentManager.setProcessEngineConfiguration(this); deploymentManager.setProcessDefinitionEntityManager(processDefinitionEntityManager);//流程定义实体管理器 deploymentManager.setDeploymentEntityManager(deploymentEntityManager);//部署实体管理器 } }
然后主要看getDefaultDeployers():进行bpmn部署器的初始化:
public Collection<? extends Deployer> getDefaultDeployers() { List<Deployer> defaultDeployers = new ArrayList<Deployer>(); //用于流程的部署 if (bpmnDeployer == null) { bpmnDeployer = new BpmnDeployer(); } //初始化bpmn部署依赖管理器(解析部署构建工厂进行了bpmnParser的关联) initBpmnDeployerDependencies(); bpmnDeployer.setIdGenerator(idGenerator); bpmnDeployer.setParsedDeploymentBuilderFactory(parsedDeploymentBuilderFactory); bpmnDeployer.setBpmnDeploymentHelper(bpmnDeploymentHelper); bpmnDeployer.setCachingAndArtifactsManager(cachingAndArtifactsManager); bpmnDeployer.setProcessDefinitionDiagramHelper(processDefinitionDiagramHelper); defaultDeployers.add(bpmnDeployer); return defaultDeployers; }
可以看到创建了bpmnDeployer部署器,并初始化bpmn部署器相关的依赖:
public void initBpmnDeployerDependencies() { if (parsedDeploymentBuilderFactory == null) { parsedDeploymentBuilderFactory = new ParsedDeploymentBuilderFactory();//解析工厂初始化 } bpmnParser引用 if (parsedDeploymentBuilderFactory.getBpmnParser() == null) { parsedDeploymentBuilderFactory.setBpmnParser(bpmnParser); } if (timerManager == null) { timerManager = new TimerManager();//定时器管理器 } if (eventSubscriptionManager == null) { eventSubscriptionManager = new EventSubscriptionManager();//事件订阅管理器 } if (bpmnDeploymentHelper == null) { bpmnDeploymentHelper = new BpmnDeploymentHelper();//流程部署帮助类 } if (bpmnDeploymentHelper.getTimerManager() == null) { bpmnDeploymentHelper.setTimerManager(timerManager); } if (bpmnDeploymentHelper.getEventSubscriptionManager() == null) { bpmnDeploymentHelper.setEventSubscriptionManager(eventSubscriptionManager); } if (cachingAndArtifactsManager == null) { cachingAndArtifactsManager = new CachingAndArtifactsManager(); } if (processDefinitionDiagramHelper == null) { processDefinitionDiagramHelper = new ProcessDefinitionDiagramHelper(); } }
可以看出在该方法里进行了bpmnParser的引用关联。并初始化了相关的(流程部署)帮助类和一些管理器(定时、事件订阅、部署缓存相关管理器、流程定义图片帮助类)。
DeploymentManager->bpmnDeployer->bpmnParser
3、仓库服务进行部署的调用
RepositoryService.createDeployment().deploy
public DeploymentBuilder createDeployment() { return commandExecutor.execute(new Command<DeploymentBuilder>() { @Override public DeploymentBuilder execute(CommandContext commandContext) { return new DeploymentBuilderImpl(RepositoryServiceImpl.this); } }); } } public Deployment deploy(DeploymentBuilderImpl deploymentBuilder) { return commandExecutor.execute(new DeployCmd<Deployment>(deploymentBuilder)); }
可以看下DeployCmd命令类:
在execute里调用了executeDeploy(commandContext)方法:
protected Deployment executeDeploy(CommandContext commandContext) { //获取刚构建的部署对象 DeploymentEntity deployment = deploymentBuilder.getDeployment(); //设置部署当前时间 deployment.setDeploymentTime(commandContext.getProcessEngineConfiguration().getClock().getCurrentTime()); //在部署时会检测已部署的相同文件的最后一条记录,如果内容相同,则不会部署 if (deploymentBuilder.isDuplicateFilterEnabled()) { //保存查到的集合 List<Deployment> existingDeployments = new ArrayList<Deployment>(); if (deployment.getTenantId() == null || ProcessEngineConfiguration.NO_TENANT_ID.equals(deployment.getTenantId())) {//TenantId不存在,通过部署名称查询数据库 //查ACT_RE_DEPLOYMENT该表 DeploymentEntity existingDeployment = commandContext.getDeploymentEntityManager().findLatestDeploymentByName(deployment.getName()); if (existingDeployment != null) { existingDeployments.add(existingDeployment); } } else {//TenantId存在 List<Deployment> deploymentList = commandContext.getProcessEngineConfiguration().getRepositoryService().createDeploymentQuery().deploymentName(deployment.getName()) .deploymentTenantId(deployment.getTenantId()).orderByDeploymentId().desc().list(); if (!deploymentList.isEmpty()) { existingDeployments.addAll(deploymentList); } } DeploymentEntity existingDeployment = null; if (!existingDeployments.isEmpty()) { existingDeployment = (DeploymentEntity) existingDeployments.get(0); } //查到且和要部署的一致,则直接返回查出来的 if ((existingDeployment != null) && !deploymentsDiffer(deployment, existingDeployment)) { return existingDeployment; } } deployment.setNew(true);//设置为一个新的定义 // Save the data //插入ACT_RE_DEPLOYMENT表(1条)和ACT_GE_BYTEARRAY表(png和bpmn定义) commandContext.getDeploymentEntityManager().insert(deployment); if (commandContext.getProcessEngineConfiguration().getEventDispatcher().isEnabled()) {//默认开启 //触发deployment entity被创建的事件(默认不执行任何操作,只是日志的输出等) commandContext.getProcessEngineConfiguration().getEventDispatcher().dispatchEvent(ActivitiEventBuilder.createEntityEvent(ActivitiEventType.ENTITY_CREATED, deployment)); } // Deployment settings Map<String, Object> deploymentSettings = new HashMap<String, Object>(); //bpmn2.0检查,默认开启 deploymentSettings.put(DeploymentSettings.IS_BPMN20_XSD_VALIDATION_ENABLED, deploymentBuilder.isBpmn20XsdValidationEnabled()); //process流程定义检查,默认开启 deploymentSettings.put(DeploymentSettings.IS_PROCESS_VALIDATION_ENABLED, deploymentBuilder.isProcessValidationEnabled()); // Actually deploy //执行真正的部署操作 commandContext.getProcessEngineConfiguration().getDeploymentManager().deploy(deployment, deploymentSettings); if (deploymentBuilder.getProcessDefinitionsActivationDate() != null) {//流程定义是否有激活日期 scheduleProcessDefinitionActivation(commandContext, deployment);//进行流程定义的挂起或定时激活 } if (commandContext.getProcessEngineConfiguration().getEventDispatcher().isEnabled()) {//默认开启 //触发entity被初始化事件 commandContext.getProcessEngineConfiguration().getEventDispatcher().dispatchEvent(ActivitiEventBuilder.createEntityEvent(ActivitiEventType.ENTITY_INITIALIZED, deployment)); } return deployment; }
主要工作:
1、创建部署对象 2、设置部署时间 3、 在部署时会检测已部署的相同文件的最后一条记录,如果内容相同,则不会部署,直接返回。 否则: 4、设置为一个新的 5、插入ACT_RE_DEPLOYMENT表(1条)和ACT_GE_BYTEARRAY表(png和bpmn定义)记录 触发deployment entity被创建的事件(默认不执行任何操作,只是日志的输出等) 6、bpmn2.0检查开启、process流程定义检查开启。 7、执行真正的部署 8、检查流程定义是否有激活日期,有则进行流程定义的挂起或定时激活
我们主要看第7步:
commandContext.getProcessEngineConfiguration().getDeploymentManager().deploy(deployment, deploymentSettings);
可以看到该步骤调用了部署管理器DeploymentManager的deploy方法:
代码:
protected List<Deployer> deployers; public void deploy(DeploymentEntity deployment, Map<String, Object> deploymentSettings) { for (Deployer deployer : deployers) { deployer.deploy(deployment, deploymentSettings); } }
可以看到循环调用了部署器的部署方法,部署器默认有BpmnDeployer\FormDeployer\RulesDeployer,此处我们主要分析BpmnDeployer:
代码如下://真正的流程部署操作
@Override public void deploy(DeploymentEntity deployment, Map<String, Object> deploymentSettings) { log.debug("Processing deployment {}", deployment.getName()); // The ParsedDeployment represents the deployment, the process definitions, and the BPMN // resource, parse, and model associated with each process definition. ParsedDeployment parsedDeployment = parsedDeploymentBuilderFactory .getBuilderForDeploymentAndSettings(deployment, deploymentSettings) .build(); //校验文件里的多个流程定义不能出现多个同样的key bpmnDeploymentHelper.verifyProcessDefinitionsDoNotShareKeys(parsedDeployment.getAllProcessDefinitions()); //通过deployment为流程定义赋更多属性(引擎版本、tenantId、deploymentId) bpmnDeploymentHelper.copyDeploymentValuesToProcessDefinitions( parsedDeployment.getDeployment(), parsedDeployment.getAllProcessDefinitions()); //为流程定义设置资源名称 bpmnDeploymentHelper.setResourceNamesOnProcessDefinitions(parsedDeployment); //判断是否需要生成图片 createAndPersistNewDiagramsIfNeeded(parsedDeployment); //为定义设置图片资源名称 setProcessDefinitionDiagramNames(parsedDeployment); if (deployment.isNew()) {//新的 //查是否存在老的并放入map返回(new:old) Map<ProcessDefinitionEntity, ProcessDefinitionEntity> mapOfNewProcessDefinitionToPreviousVersion = getPreviousVersionsOfProcessDefinitions(parsedDeployment); //给流程定义初始化流程定义id,设置版本号为1或者(根据是否有旧的版本号+1) setProcessDefinitionVersionsAndIds(parsedDeployment, mapOfNewProcessDefinitionToPreviousVersion); //流程定义入库,并给流程定义设置候选人也入库 persistProcessDefinitionsAndAuthorizations(parsedDeployment); //取消旧的消息、信号、定时启动事件等及删库,且入库新的并绑定对应事件 updateTimersAndEvents(parsedDeployment, mapOfNewProcessDefinitionToPreviousVersion); dispatchProcessDefinitionEntityInitializedEvent(parsedDeployment);//触发流程定义被初始化事件 } else { //不是新的,则查出来的旧的,并给当前定义设置相关属性(貌似可用于更新(因为版本号没有增加)) makeProcessDefinitionsConsistentWithPersistedVersions(parsedDeployment); } //缓存操作:流程定义放入全局流程定义缓存map和全局流程定义treeNode缓存map, //还有一个deployedArtifacts部署记录map(class org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntityImpl:实例list) cachingAndArtifactsManager.updateCachingAndArtifacts(parsedDeployment); for (ProcessDefinitionEntity processDefinition : parsedDeployment.getAllProcessDefinitions()) { BpmnModel bpmnModel = parsedDeployment.getBpmnModelForProcessDefinition(processDefinition); //更新流程定义中国际化数据 createLocalizationValues(processDefinition.getId(), bpmnModel.getProcessById(processDefinition.getKey())); } }
可以看出主要执行的操作:
1、进行了bpmn xml的解析和构建并保存在ParsedDeployment对象里: 该类相关数据结构: protected DeploymentEntity deploymentEntity; protected List<ProcessDefinitionEntity> processDefinitions; protected Map<ProcessDefinitionEntity, BpmnParse> mapProcessDefinitionsToParses; protected Map<ProcessDefinitionEntity, ResourceEntity> mapProcessDefinitionsToResources; 2、校验文件里的多个流程定义不能出现多个同样的key 3、通过deployment为流程定义赋更多属性(引擎版本、tenantId、deploymentId) 4、为流程定义设置资源名称 5、判断是否需要生成图片,不存在则创建diagram(入库ACT_GE_BYTEARRAY) 6、为定义设置图片资源名称 7、isNew是否为创建新的: 是: 7.1 查是否存在老的定义并放入map返回(new:old) 7.2 给流程定义初始化流程定义id,设置版本号为1或者(根据是否有旧的版本号+1) 7.3 流程定义入库,并给流程定义设置候选人也入库(流程定义入库ACT_RE_PROCDEF表; 流程启动候选人组入库ACT_RU_IDENTITYLINK: getCandidateStarterUsers\getCandidateStarterGroups) 7.4 取消旧的消息、信号、定时启动事件等及删库,且入库新的并绑定对应事件 (ACT_RU_EVENT_SUBSCR,ACT_RU_TIMER_JOB) 7.5 触发流程定义被初始化事件 否: 7.1 不是新的,则查出来的旧的,并给当前定义设置相关属性(貌似可用于更新(因为版本号没有增加)) 8、缓存操作:流程定义放入全局流程定义缓存map和全局流程定义treeNode缓存map, //还有一个deployedArtifacts部署记录map(class org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntityImpl:实例list) DeploymentCache<ProcessDefinitionCacheEntry> ProcessDefinitionInfoCache Map<Class<?>, List<Object>> deployedArtifacts; 9、更新所有流程定义中的国际化数据 相关说明: //查找localization下语言为es的下id为id下属性为name //例如结构{"localization":{"es":{"id1":{"name":"123"}}}} 返回"123" JsonNode localizationNode = infoNode.path("localization").path(language).path(id).path(propertyName); 上面国际化数据通过查询ACT_PROCDEF_INFO表。
首先分析代码:
ParsedDeployment parsedDeployment = parsedDeploymentBuilderFactory .getBuilderForDeploymentAndSettings(deployment, deploymentSettings) .build();
如下:
public class ParsedDeploymentBuilderFactory { protected BpmnParser bpmnParser; public BpmnParser getBpmnParser() { return bpmnParser; } public void setBpmnParser(BpmnParser bpmnParser) { this.bpmnParser = bpmnParser; } public ParsedDeploymentBuilder getBuilderForDeployment(DeploymentEntity deployment) { return getBuilderForDeploymentAndSettings(deployment, null); } public ParsedDeploymentBuilder getBuilderForDeploymentAndSettings(DeploymentEntity deployment, Map<String, Object> deploymentSettings) { return new ParsedDeploymentBuilder(deployment, bpmnParser, deploymentSettings); } }
可以看到主要在new ParsedDeploymentBuilder(deployment, bpmnParser, deploymentSettings)该行:
public class ParsedDeploymentBuilder { private static final Logger log = LoggerFactory.getLogger(ParsedDeploymentBuilder.class); protected DeploymentEntity deployment; protected BpmnParser bpmnParser; protected Map<String, Object> deploymentSettings; public ParsedDeploymentBuilder(DeploymentEntity deployment, BpmnParser bpmnParser, Map<String, Object> deploymentSettings) { this.deployment = deployment; this.bpmnParser = bpmnParser; this.deploymentSettings = deploymentSettings; } public ParsedDeployment build() { List<ProcessDefinitionEntity> processDefinitions = new ArrayList<ProcessDefinitionEntity>(); Map<ProcessDefinitionEntity, BpmnParse> processDefinitionsToBpmnParseMap = new LinkedHashMap<ProcessDefinitionEntity, BpmnParse>(); Map<ProcessDefinitionEntity, ResourceEntity> processDefinitionsToResourceMap = new LinkedHashMap<ProcessDefinitionEntity, ResourceEntity>(); for (ResourceEntity resource : deployment.getResources().values()) { if (isBpmnResource(resource.getName())) {//判断资源后缀,支持"bpmn20.xml", "bpmn" log.debug("Processing BPMN resource {}", resource.getName()); //主要进行bpmnModel的构建转换,bpmn2.0,流程校验,di解析等 BpmnParse parse = createBpmnParseFromResource(resource); for (ProcessDefinitionEntity processDefinition : parse.getProcessDefinitions()) { processDefinitions.add(processDefinition); processDefinitionsToBpmnParseMap.put(processDefinition, parse); processDefinitionsToResourceMap.put(processDefinition, resource); } } } return new ParsedDeployment(deployment, processDefinitions, processDefinitionsToBpmnParseMap, processDefinitionsToResourceMap); } protected BpmnParse createBpmnParseFromResource(ResourceEntity resource) { String resourceName = resource.getName(); ByteArrayInputStream inputStream = new ByteArrayInputStream(resource.getBytes()); //构建BpmnParse 解析器 BpmnParse bpmnParse = bpmnParser.createParse() .sourceInputStream(inputStream) .setSourceSystemId(resourceName) .deployment(deployment) .name(resourceName); if (deploymentSettings != null) { // Schema validation if needed if (deploymentSettings.containsKey(DeploymentSettings.IS_BPMN20_XSD_VALIDATION_ENABLED)) {//bpmn2.0校验 bpmnParse.setValidateSchema((Boolean) deploymentSettings.get(DeploymentSettings.IS_BPMN20_XSD_VALIDATION_ENABLED)); } // Process validation if needed if (deploymentSettings.containsKey(DeploymentSettings.IS_PROCESS_VALIDATION_ENABLED)) {//process流程规范检查 bpmnParse.setValidateProcess((Boolean) deploymentSettings.get(DeploymentSettings.IS_PROCESS_VALIDATION_ENABLED)); } } else { // On redeploy, we assume it is validated at the first deploy bpmnParse.setValidateSchema(false); bpmnParse.setValidateProcess(false); } bpmnParse.execute();//执行解析(初始化行为类) return bpmnParse; } ......省略 }
看到:
1、在build方法里调用了 BpmnParse parse = createBpmnParseFromResource(resource);
2、在createBpmnParseFromResource方法里通过bpmnParser创建了bpmnParse,在bpmnParse.execute里通过bpmnParserHandlers.parseElement(this, process)进行了元素的行为的初始化
综上:
1、resourceService.deploy->2、deploymentManager.deploy->3、bpmnDeployer.deploy->4、bpmnParse.execute(
execute方法进行xml bpmnModel的转换及bpmnParserHander.parseElement(其实该步骤主要用于每个节点元素行为类的设置)
)
其中bpmnParse和bpmnParserHandler都通过bpmnParser创建和获取。
核心在bpmnParse.execute方法里,可以分析一下execute的代码:
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) { ProcessValidator processValidator = processEngineConfiguration.getProcessValidator(); if (processValidator == null) { LOGGER.warn("Process should be validated, but no process validator is configured on the process engine configuration!"); } else { List<ValidationError> validationErrors = processValidator.validate(bpmnModel); if (validationErrors != null && !validationErrors.isEmpty()) { StringBuilder warningBuilder = new StringBuilder(); StringBuilder errorBuilder = new StringBuilder(); for (ValidationError error : validationErrors) { if (error.isWarning()) { warningBuilder.append(error.toString()); warningBuilder.append("\n"); } else { errorBuilder.append(error.toString()); errorBuilder.append("\n"); } } // Throw exception if there is any error if (errorBuilder.length() > 0) { throw new ActivitiException("Errors while parsing:\n" + errorBuilder.toString()); } // Write out warnings (if any) if (warningBuilder.length() > 0) { LOGGER.warn("Following warnings encountered during process validation: " + warningBuilder.toString()); } } } } bpmnModel.setSourceSystemId(sourceSystemId); bpmnModel.setEventSupport(new ActivitiEventSupport()); // Validation successful (or no validation) // Attach logic to the processes (eg. map ActivityBehaviors to bpmn model elements) applyParseHandlers();//执行子流程的解析 // Finally, process the diagram interchange info processDI(); } 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 applyParseHandlers() { sequenceFlows = new HashMap<String, SequenceFlow>(); for (Process process : bpmnModel.getProcesses()) { currentProcess = process; if (process.isExecutable()) { bpmnParserHandlers.parseElement(this, process);//在此步骤的解析操作中会把流程定义实体加入processDefinitions集合 } } }
可以看出调用了bpmnModel = converter.convertToBpmnModel(streamSource, validateSchema, enableSafeBpmnXml);通过BpmnXMLConverter进行了解析并转换为bpmnModel实体。
待补充....