上下文与流程变量有关。流程变量是保存与流程实例相关信息的键-值对。由于上下文必须能被存储到数据库,将会稍会约束使用。
10.1.访问变量
org.jbpm.context.exe.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
classes that are persistable with hibernate
空类型null值同样可以被持久化保存。
所有其他类型能正常地存储到流程变量中。但当你试图保存流程实例时将导致一个异常。
如何配置jBPM以能够在变量中存储HIBERNATE持久化对象,请参看Storing hibernate persistent objects。
10.2.变量的生命周期
变量不必再流程定义文件中(流程归档中)声明。在运行时,你可以随意放置任何对象到变量中。如果变量不存在,它将会被建立。这和普通的java.util.Map类似。
变量可以使用如下语句删除:
ContextInstance.deleteVariable(String variableName);
ContextInstance.deleteVariable(String variableName, Token token);
自动改变类型以及被支持。这意味着允许使用一个不同类型的值覆盖一个变量。当然,你应该尽力限制类型改变的数量,因为更新一个普通的列将带来更多的数据库消耗。
10.3.变量持久化
变量是流程实例的一部分。保存流程实例到数据库中,保持流程实例和数据库同步。变量由于流程实例在数据库中的保存(更新)操作而在数据在被创建、更新、和删除。更多信息请看Chapter 7, Persistence.
10.4.变量范围
每条执行路径(阅读:Token)都有它所属的流程变量集合。请求一个变量往往在一个Token(令牌)中完成。流程实例有一个令牌树(请看graph oriented programming)。当请求一个变量而没有指定一个令牌时,默认的令牌为根令牌。
变量查询递归到给定令牌的父母令牌.这种行为与编程语言的变量范围类似。
当不存在的变量被设置到令牌中,变量将被创建在根令牌。这意味着每个变量默认就是整个流程范围。为使得变量基于本令牌(局部变量),你可以用如下方法明确创建:
ContextInstance.createVariable(String name, Object value, Token token);
10.4.1. 变量重载
变量重载一为之每个执行路径能够用相同的名称拥有自己的一份变量的拷贝。他们能被独立的对待,因此可以是不同的类型。如果你在相同的转换上启动了多条并发的执行路径,变量重载将十分有趣。唯一的事情是区分哪些执行路径是它们各自的变量集合。
10.4.2.变量的覆盖
变量覆盖意味着执行的嵌套路径中的变量覆盖了执行中更为全局的变量。一般的,执行的嵌套路径与并发性有关:一般的,嵌套执行路线涉及到并发问题: 在form和join之间的执行路线是到达fork的执行路线的. 比如,如果你有变量 'contact'在流程实例范围, 你可以在嵌套的执行路线'shipping'和'billing'重写这个变量.
10.4.3.任务实例变量范围
更多关于任务实例变量的信息,请看 Section 11.4, “Task instance variables”.
10.5 瞬时变量
当流程实例被持久化到数据库中,普通变量可以同时作为流程的一部分被持久化。在某些情况下你可能需要在ige代理类中使用一个变量,但你不想把它存储到数据中。比如一个你想从jBPM外部传递数据库连接到一个代理类。这可以通过瞬时变量来完成。
瞬时变量的生命周期和流程实例的java对象相同。
由于他们的特性,瞬时变量不与令牌相关。所以对一个流程实例只有一个瞬时变量的Map。瞬时变量可以在上下文实例中通过它们自己的方法集合来访问,你不必在流程定义文件processdefinition.xml中声明。
Object ContextInstance.getTransientVariable(String name);
void ContextInstance.setTransientVariable(String name, Object value);
10.6.定制变量持久化
变量通过2个步骤被存储在数据库中:
user-java-object <---> converter <---> variable instance
变量存储在变量实例VariableInstances。VariableInstances的数量与Hibernate在数据库中的域映射。在jBPM默认的配置中,有6种VariableInstances被使用:
DateInstance (with one java.lang.Date field that is mapped to a Types.TIMESTAMP in the database)
DoubleInstance (with one java.lang.Double field that is mapped to a Types.DOUBLE in the database)
StringInstance (with one java.lang.String field that is mapped to a Types.VARCHAR in the database)
LongInstance (with one java.lang.Long field that is mapped to a Types.BIGINT in the database)
HibernateLongInstance (this is used for hibernatable types with a long id field. One java.lang.Object field is mapped as a reference to a hibernate entity in the database)
HibernateStringInstance (this is used for hibernatable types with a string id field. One java.lang.Object field is mapped as a reference to a hibernate entity in the database)
Converters在java-user-objects和能被VariableInstances存储的java对象之间进行转换。因此,当一个流程变量用:ContextInstance.setVariable(String variableName, Object value)进行设置,那么值将随意地通过Converter被转换。然后转换过的对象将被存储到VariableInstances。Converters实现了下面的接口:
public interface Converter extends Serializable {
boolean supports(Object value);
Object convert(Object o);
Object revert(Object o);
}
Converters是非强制的,Converters必须在jBPM class loader可用。
user-java-objects被转换并存储到变量实例的方式是在org/jbpm/context/exe/jbpm.varmapping.properties文件配置的。要定制这些属性文件,需要放一个修改版本在classpath的根路径中,如Section 6.2, “Configuration files” 中所述,属性文件的每行指定2或3个类名,通过空格隔开:user-java-object的类名,可选的转变器的类名和变量实例的名字。当你引用你定制的转换器,确保他们在jBPM class path中。当你引用定制的变量实例,他们必须在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>
该片段指定了所有java.lang.Boolean类型的对象必须使用BooleanToStringConverter转换器来转换,并且结果对象(是一个String值)将被存储到一个类型为StringInstance的变量实例对象。
如果没有指定Converter
<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变量实例而没有被转化。
2008年10月9日星期四
jBPM用户指南-CH10
第十章 上下文
订阅:
博文评论 (Atom)


没有评论:
发表评论