第10章. 上下文(Context)

来源:互联网 发布:淘宝lolita店铺推荐 编辑:程序博客网 时间:2024/04/28 06:20

第10章. Context

上下文是同流程变量相关的。流程变量是维护同流程实例相关的键-值对的信息. 由于上下文必须被存储在数据库中, 将会稍微约束使用。

10.1. 访问变量

org.jbpm.context.exe.ContextInstance作为提供流程变量服务的中央接口。你可以从ProcessInstance 获得ContextInstance :

ProcessInstance processInstance = ...;ContextInstance contextInstance = (ContextInstance) processInstance.getInstance(ContextInstance.class);

最基本操作是

void ContextInstance.setVariable(String variableName, Object value);void ContextInstance.setVariable(String variableName, Object value, Token token);Object ContextInstance.getVariable(String variableName);Object ContextInstance.getVariable(String variableName, Token token);

变量名是 java.lang.String. 默认情况下, jBPM支持下列值类型:

 

  • java.lang.String
  • java.lang.Boolean
  • java.lang.Character
  • java.lang.Float
  • java.lang.Double
  • java.lang.Long
  • java.lang.Byte
  • java.lang.Short
  • java.lang.Integer
  • java.util.Date
  • byte[]
  • java.io.Serializable
  • 使用hibernate持久化的类

 

当然无类型的空值也可以被持久的保存.

所有其它的类型也可没有问题的保存在流程变量中。但时当你试图保存流程实例时将会引起异常.

要配置jBPM来在变量中保存hibernate持久对象, 参见存储hibernate持久对象.

10.2. 变量生命周期

变量不必在流程归档中声明。在运行时,你可以将任何Java对象放在变量中。如果变量不存在,它将被创建。同简明的java.util.Map一样。

变量可被删除:

ContextInstance.deleteVariable(String variableName);ContextInstance.deleteVariable(String variableName, Token token);

已知限制:类型的自动转换不支持。这意味着不充许用一个不同类型的值来重写一个变量。要这样做,旧的变量必须首先被删掉。当然用相同类型的值来重写变量是支持的

当然,由于要创建一个以上的数据库通信然后再进行一列的更新,你应譔尝试限制类型转换的数量.

10.3. 变量持久化

变量是流程实例的一部分. 保存流程实例到数据库,保持数据库同流程实例同步.作为在数据库中保存或更新流程实例的结果,变量从数据库被建立 ,更新和删除?.更多信息,参看第7章, 持久化.

10.4. 变量范围

每一个执行路径(read: token)有其自已的一套流程变量. 通常是在一个令牌上请求一个变量. 流程实例有一个令牌树 (see 面向图形编程). 在请求变量时没有指定令牌,默认的令牌是根令牌(token).

变量查询递归到给定令牌的父令牌. 这个行为同程序开发语言里的变量范围是相似的.

当在令牌上设置不存在变量,那么变量就在根令牌上被建立.这就是说每个变量默认就是整个流程范围. 如果想建立一个令牌的局部变量,必须显式的使用API:

ContextInstance.createVariable(String name, Object value, Token token);

10.4.1. 变量重载( overloading)

变量重载意味着意味着每个执行路线都有自己的同名字的变量复制. 它们被当作独立的,并且因此可是不同类型的. 当你在一个转换(transition)里调用多个并发的执行路线的时候,变量重载将要引起注意。此时唯一能区分这些执行路线的东西是它们各自的一组变量.

10.4.2. 变量覆盖(overriding)

变量重写是说在嵌套中的执行路线里的变量的值将覆盖更高层中执行路线中变量的值. 一般的,嵌套执行路线涉及到并发问题: 在fork和join之间的执行路线是到达fork的执行路线的子路线. 比如,如果你有变量'contact'在流程实例范围, 你可以在嵌套的执行路线'shipping'和'billing'重写这个变量.

10.4.3. 任务实例变量范围

更多有关任务实例变量的信息, 参见 Section 11.4, “任务实例变量”.

10.5. 瞬时变量(Transient variables)

当流程实例持久化到数据库中,正常变量也作为流程实例的一部分被持久化了.某些状态下你可能想在委托类里用变量, 但是你不想把它储存在数据库中. 比如你想从JBPM的外部传送一个数据库链接到一个委托类.这就可以由临时变量来做.

临时变量的生命周期同ProcessInstance java对象一样.

由于这个自然特性,临时变量同令牌无关. 因此对于一个流程实例对象只有一个临时变量的map.

临时变量在上下文实例中可以从它们自己的方法组来访问, 不需要在processdefinition.xml中声明。

Object ContextInstance.getTransientVariable(String name);void ContextInstance.setTransientVariable(String name, Object value);

10.6. 定制变量持久化

变量保存在数据库中有两个步骤:

user-java-object <---> converter <---> variable instance

变量保存在量实例(VariableInstance)中.VariableInstance的成员被被hibernate映射到数据库的字段. 在jBPM默认的配置中, 6种类型的VariableInstances被使用:

  • DateInstance (使用一个影射到数据库中Types.TIMESTAMP的java.lang.Date字段)

  • DoubleInstance (使用一个影射到数据库中Types.DOUBLE的java.lang.Double字段)

  • StringInstance (使用一个影射到数据库中Types.VARCHAR的java.lang.String字段)

  • LongInstance (使用一个影射到数据库中Types.BIGINT的java.lang.Long字段)

  • HibernateLongInstance (用于可被hibernate化类型的长整型id字段,一个java.lang.Object字段被作为对一个数据库中hibernate实体引用的影射。)

  • HibernateStringInstance (用于可被hibernate化类型的字符串id字段,一个java.lang.Object字段被作为对一个数据库中hibernate实体引用的影射。)

转换器用来在java-user-objects和可以被变量实例存储的java对象之间进行转换,因此当一个流程变量被用例如 ContextInstance.setVariable(String variableName, Object value)来设置时,值将可选的使用转换器转换。然后被转换的对象将被存储到变量实例。转换器实现了下面的接口:

public interface Converter extends Serializable {  boolean supports(Object value);  Object convert(Object o);  Object revert(Object o);}

转变器是可选的. 转变器必须对jBPM 类装载器可用.

user-java-objects被转换并保存在变量实例的方法在 org/jbpm/context/exe/jbpm.varmapping.properties文件中配置 . 定制这个属性文件, 把修改后的版本放到classpath的根, 如同章节5.2, “配置文件”中所解释的,属性文件每行都指明2或3个类名有空格搁开: the user-java-object的类名,可选的转变器的类名和变量实例的名字.当你引用你定制的转变器, 确定他们在jBPM类路径中 . 当你引用你定制的变量实例, 他们必须在 jBPM class path 并且hibernate 映射文件 org/jbpm/context/exe/VariableInstance.hbm.xml 必须更新以包含定制的 VariableInstance的子类.

例如, 看一下下面的在文件org/jbpm/context/exe/jbpm.varmapping.xml中的片断.

    <jbpm-type>      <matcher>        <bean class="org.jbpm.context.exe.matcher.ClassNameMatcher">          <field name="className"><string value="java.lang.Boolean" /></field>        </bean>      </matcher>      <converter class="org.jbpm.context.exe.converter.BooleanToStringConverter" />      <variable-instance class="org.jbpm.context.exe.variableinstance.StringInstance" />    </jbpm-type>

这行指明了所有类型为Boolean的类型被转换器 BooleanToStringConverter转换并且结果对象(a String)将被保存在StringInstance类型的变量实例对象中.
如果没有转变器:

    <jbpm-type>      <matcher>        <bean class="org.jbpm.context.exe.matcher.ClassNameMatcher">          <field name="className"><string value="java.lang.Long" /></field>        </bean>      </matcher>      <variable-instance class="org.jbpm.context.exe.variableinstance.LongInstance" />    </jbpm-type>

表明Long对象将被存储在LongInstance类型的变量实例中不需要任何改变.

原创粉丝点击