服务热线
135-6963-3175
流程的部署主要通过DeployCmd类进行:
查看部分核心代码:
public Deployment execute(CommandContext commandContext) { // Backwards compatibility with Activiti v5 //activiti5兼容开启 if (commandContext.getProcessEngineConfiguration().isActiviti5CompatibilityEnabled() && deploymentBuilder.getDeploymentProperties() != null && deploymentBuilder.getDeploymentProperties().containsKey(DeploymentProperties.DEPLOY_AS_ACTIVITI5_PROCESS_DEFINITION) && deploymentBuilder.getDeploymentProperties().get(DeploymentProperties.DEPLOY_AS_ACTIVITI5_PROCESS_DEFINITION).equals(Boolean.TRUE)) { return deployAsActiviti5ProcessDefinition(commandContext); } //执行部署 return 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、在部署时会检测已部署的相同文件的最后一条记录,如果内容相同,则不会部署
查到且和要部署的一致,则直接返回查出来的
否则:
2.1 设置为一个新的定义
2.2 插入ACT_RE_DEPLOYMENT表(1条)和ACT_GE_BYTEARRAY表(png和bpmn定义)
2.3设置bpmn2.0检查开启,process流程定义检查开启
3、执行真正的部署
4、流程定义是否有激活日期,有则进行流程定义的挂起或定时激活
分析部署代码:
commandContext.getProcessEngineConfiguration().getDeploymentManager().deploy(deployment, deploymentSettings);
在deploymentManager里调用了BpmnDeployer的deploy方法。查看BpmnDeployer的deploy方法://真正的流程部署
@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表