技术交流28群

服务热线

135-6963-3175

微信服务号

activiti变量相关操作 更新时间 2022-3-20 浏览2186次

看代码:

setVariableLocal用于设置进当前execution变量

public Object setVariableLocal(String variableName, Object value, boolean fetchAllVariables) {
    return setVariableLocal(variableName, value, getSourceActivityExecution(), fetchAllVariables);
}
public Object setVariableLocal(String variableName, Object value, ExecutionEntity sourceActivityExecution, boolean fetchAllVariables) {
    if (fetchAllVariables == true) {
      // If it's in the cache, it's more recent
      //1.如果在缓存中,则更新(并触发变量被更新事件)
      if (usedVariablesCache.containsKey(variableName)) {
        updateVariableInstance(usedVariablesCache.get(variableName), value, sourceActivityExecution);
      }
      //2.确保变量实例集合实例初始化
      ensureVariableInstancesInitialized();
      //3.通过实例的变量获取
      VariableInstanceEntity variableInstance = variableInstances.get(variableName);
      if (variableInstance == null) {
        //4.通过缓存变量获取
        variableInstance = usedVariablesCache.get(variableName);
      }
      if (variableInstance == null) {
        //不存在则创建变量入库
        createVariableLocal(variableName, value);
      } else {
        //更新变量
        updateVariableInstance(variableInstance, value, sourceActivityExecution);
      }
      return null;
    } else {
      if (usedVariablesCache.containsKey(variableName)) {//1.查缓存
        //更新缓存
        updateVariableInstance(usedVariablesCache.get(variableName), value, sourceActivityExecution);
      } else if (variableInstances != null && variableInstances.containsKey(variableName)) {
        //变量实例集合
        updateVariableInstance(variableInstances.get(variableName), value, sourceActivityExecution);
      } else {
        //通过变量名和执行id查ACT_RU_VARIABLE表
        VariableInstanceEntity variable = getSpecificVariable(variableName);
        if (variable != null) {
          updateVariableInstance(variable, value, sourceActivityExecution);
        } else {
          //创建变量,入库
          variable = createVariableInstance(variableName, value, sourceActivityExecution);
        }
        //缓存
        usedVariablesCache.put(variableName, variable);
      }
      return null;
    }
  }

分析上面代码,主要进行了如下操作:

1.是否查所有:
    是:
        1.1 在usedVariablesCache缓存中,更新变量缓存(不存在则入库ACT_HI_VARINST历史变量实例表)
        1.2 确保变量实例集合实例初始化
             查ACT_RU_VARIABLE ,获取当前执行实例的变量集合放入实例变量集合。
        1.3 变量实例集合不存在则从步骤1的缓存中取:
             取不到则创建入库。
             取到则更新变量。
    否:
        1.1查缓存
        1.2查变量实例集合
        1.3通过变量名和执行id查ACT_RU_VARIABLE表
           存在则更新
           不存在则创建并入库,并放入缓存,放入变量实例Map集合

步骤1用到了变量类型,可以在ProcessEngineConfigurationImpl的init方法中看到调用了initVariableTypes方法:

代码如下:

public void initVariableTypes() {
    if (variableTypes == null) {
      variableTypes = new DefaultVariableTypes();
      if (customPreVariableTypes != null) {
        for (VariableType customVariableType : customPreVariableTypes) {
          variableTypes.addType(customVariableType);
        }
      }
      variableTypes.addType(new NullType());
      variableTypes.addType(new StringType(getMaxLengthString()));
      variableTypes.addType(new LongStringType(getMaxLengthString() + 1));
      variableTypes.addType(new BooleanType());
      variableTypes.addType(new ShortType());
      variableTypes.addType(new IntegerType());
      variableTypes.addType(new LongType());
      variableTypes.addType(new DateType());
      variableTypes.addType(new JodaDateType());
      variableTypes.addType(new JodaDateTimeType());
      variableTypes.addType(new DoubleType());
      variableTypes.addType(new UUIDType());
      variableTypes.addType(new JsonType(getMaxLengthString(), objectMapper));
      variableTypes.addType(new LongJsonType(getMaxLengthString() + 1, objectMapper));
      variableTypes.addType(new ByteArrayType());
      variableTypes.addType(new SerializableType(serializableVariableTypeTrackDeserializedObjects));
      variableTypes.addType(new CustomObjectType("item", ItemInstance.class));
      variableTypes.addType(new CustomObjectType("message", MessageInstance.class));
      if (customPostVariableTypes != null) {
        for (VariableType customVariableType : customPostVariableTypes) {
          variableTypes.addType(customVariableType);
        }
      }
    }
  }

有基本类型,并可加入自定义扩展类型。

接下来看非local变量:

setVariable用于设置进root execution processInstance级别的

protected void setVariable(String variableName, Object value, ExecutionEntity sourceExecution, boolean fetchAllVariables) {
    if (fetchAllVariables == true) {
      // If it's in the cache, it's more recent
      if (usedVariablesCache.containsKey(variableName)) {//如果该变量在缓存中,则更新它,否则保存
        updateVariableInstance(usedVariablesCache.get(variableName), value, sourceExecution);
      }
      // If the variable exists on this scope, replace it
      //1.如果此范围内存在变量,则替换它
      if (hasVariableLocal(variableName)) {
        setVariableLocal(variableName, value, sourceExecution, true);
        return;
      }
      //2.查ACT_RU_EXECUTION表
      //否则,在层次结构上向上(我们试图将它放在尽可能高的位置)
      // Otherwise, go up the hierarchy (we're trying to put it as high as possible)
      VariableScopeImpl parentVariableScope = getParentVariableScope();
      if (parentVariableScope != null) {
        if (sourceExecution == null) {
          parentVariableScope.setVariable(variableName, value);
        } else {
          parentVariableScope.setVariable(variableName, value, sourceExecution, true);
        }
        return;
      }
      // We're as high as possible and the variable doesn't exist yet, so
      // we're creating it
      if (sourceExecution != null) {
        //
        createVariableLocal(variableName, value, sourceExecution);
      } else {
        createVariableLocal(variableName, value);
      }
    } else {
      // Check local cache first
      if (usedVariablesCache.containsKey(variableName)) {
        updateVariableInstance(usedVariablesCache.get(variableName), value, sourceExecution);
      } else if (variableInstances != null && variableInstances.containsKey(variableName)) {
        updateVariableInstance(variableInstances.get(variableName), value, sourceExecution);
      } else {
        // Not in local cache, check if defined on this scope
        // Create it if it doesn't exist yet
        VariableInstanceEntity variable = getSpecificVariable(variableName);
        if (variable != null) {
          updateVariableInstance(variable, value, sourceExecution);
          usedVariablesCache.put(variableName, variable);
        } else {
          VariableScopeImpl parent = getParentVariableScope();
          if (parent != null) {
            if (sourceExecution == null) {
              parent.setVariable(variableName, value, fetchAllVariables);
            } else {
              parent.setVariable(variableName, value, sourceExecution, fetchAllVariables);
            }
            return;
          }
          variable = createVariableInstance(variableName, value, sourceExecution);
          usedVariablesCache.put(variableName, variable);
        }
      }
    }
  }

分析上面代码操作:

1、是否查所有:
    是:
        1.1 如果该变量在usedVariablesCache缓存中,则更新它,否则保存
        1.2 如果transientVariabes此范围内存在变量,则替换它    
             否则初始化variableInstances集合并查数据放入数据:存在要操作的,则调用上面的setVariableLocal方法
        1.3 查ACT_RU_EXECUTION表
            否则,在层次结构上向上(我们试图将它放在尽可能高(当前execute的parent的变量范围)的位置)   
    否:
        1.1如果在usedVariablesCache缓存中,则更新它,否则保存库
        1.2如果在variableInstances变量实例map中,则更新它,否则保存库
        1.3 查库更新 放入缓存中
             存在:更新缓存或入库,放入usedVariablesCache缓存中
             库不存:则放入更高级别的执行实例中;

接下来看:

VariableScopeImpl类的setTransientVariableLocal(比如在CompleteTaskCmd完成任务时候就调用了下面方法)

public void setTransientVariable(String variableName, Object variableValue) {
    VariableScopeImpl parentVariableScope = getParentVariableScope();
    if (parentVariableScope != null) {
      parentVariableScope.setTransientVariable(variableName, variableValue);
      return;
    }
    setTransientVariableLocal(variableName, variableValue);
}
public void setTransientVariableLocal(String variableName, Object variableValue) {
    if (transientVariabes == null) {
      transientVariabes = new HashMap<String, VariableInstance>();
    }
    transientVariabes.put(variableName, new TransientVariableInstance(variableName, variableValue));
}

发现只进行了本地map的保存并没有操作数据库。