技术交流28群

服务热线

135-6963-3175

微信服务号

activti之流程文件的部署 更新时间 2022-3-18 浏览1994次

我们的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实体。

待补充....