`

【转】JBPM深入解析之变量设计

 
阅读更多

在流程的流转的过程中,很多时候我们需要根据不同的实际情况传入一些初始化数据,以便完成我们个性化的业务需求;同时很多时候我们需要在不同的节点 之间共享一些业务数据,特别是一些节点要以前一节点的输出作为输入等;变量对于流程引擎来说很重要,可以说没有变量,那么我们就不能运行时动态的设置和传 入一些数据,这将极大的限制流程的灵活性!
      变量类型
       全局变量,所有的节点都可以获取并设置该变量的值
       局部变量,只在该节点及其子节点可以获取并设置该变量的值
      变量的传入
       在流程定义中进行变量的定义

 

<? xml version="1.0" encoding="UTF-8" ?>

< process  name ="EndMultiple"  xmlns ="http://jbpm.org/4.4/jpdl" >

  
< start  g ="16,96,48,48" >
    
< transition  to ="get return code"  name ="" />
  
</ start >

  
< state  g ="96,94,111,52"  name ="get return code" >
    
< transition  g ="151,60:-36,11"  name ="200"  to ="ok" />
    
< transition  g =":-16,-27"  name ="400"  to ="bad request" />
    
< transition  g ="151,183:-33,-32"  name ="500"  to ="internal server error" />
  
</ state >

  
< end  g ="238,37,48,48"  name ="ok" />
  
< end  g ="238,98,48,48"  name ="bad request" />
  
< end  g ="240,160,48,48"  name ="internal server error" />
  
  
< variable     name ="msg"  init-expr ="jbpm"  type ="string" >       
  
</ variable >
  
      
< null ></ null >
</ variable >

</ process >


       在启动流程流程实例的时候传入全局变量

    Map < String, Object >  variables  =   new  HashMap < String, Object > ();
    variables.put(
" category " " big " );
    variables.put(
" dollars " 100000 );
    Execution execution 
=  executionService.startProcessInstanceByKey( " TaskVariables " , variables);

       在唤醒那些可外部唤醒类型的节点时候传入局部变量

 

    variables  =   new  HashMap < String, Object > ();
    variables.put(
" category " " small " );
    variables.put(
" lires " 923874893 );
    taskService.completeTask(taskId, variables)

       在任务存在的情况下,可以在任务等待外部唤醒时进行局部变量的设置

    variables  =   new  HashMap < String, Object > ();
    variables.put(
" category " " small " );
    variables.put(
" lires " 923874893 );    
    taskService.setVariables(taskId, variables);

       在任何时候都可以通过执行服务传入设置全局变量

 

    variables  =   new  HashMap < String, Object > ();
    variables.put(
" category " " small " );
    variables.put(
" lires " 923874893 );    
    executionService.setVariable(execution.getId(),variables)

 

    variables  =   new  HashMap < String, Object > ();
    variables.put(
" category " " small " );
    variables.put(
" lires " 923874893 );    
    executionService.signalExecutionById(execution.getId(),variables);

      变量架构设计   

      
      TypeSet、DefaultTypeSet
      TypeSet定义了流程引擎中通过变量类型和matcher两种方式查找变量类型的接口;DefaultTypeSet对TypeSet的接口进行了实现,并定义了一个List<TypeMapping>来装载所有的变量类型的映射变量实例。
      TypeSet

 

package  org.jbpm.pvm.internal.type;

/**
 * 
@author  Tom Baeyens
 
*/
public   interface  TypeSet {

  Type findTypeByMatch(String key, Object value);
  Type findTypeByName(String typeName);

}


      DefaultTypeSet

 

package  org.jbpm.pvm.internal.type;

import  java.io.Serializable;
import  java.util.ArrayList;
import  java.util.List;

/**
 * 
@author  Tom Baeyens
 
*/
public   class  DefaultTypeSet  implements  TypeSet, Serializable {

  
private   static   final   long  serialVersionUID  =   1L ;

  
protected  List < TypeMapping >  typeMappings;

  
public  Type findTypeByMatch(String key, Object value) {
    
if  (typeMappings != null ) {
      
for  (TypeMapping typeMapping: typeMappings) {
        
if  (typeMapping.matches(key, value)) {
          
return  typeMapping.getType();
        }
      }
    }
    
    
return   null ;
  }

  
public  Type findTypeByName(String typeName) {
    
if  ( (typeMappings != null )
           
&&  (typeName != null )
       ) {
      
for  (TypeMapping typeMapping: typeMappings) {
        Type type 
=  typeMapping.getType();
        
if  (typeName.equals(type.getName())) {
          
return  type;
        }
      }
    }
    
return   null ;
  }

  
public   void  addTypeMapping(TypeMapping typeMapping) {
    
if  (typeMappings == null ) {
      typeMappings 
=   new  ArrayList < TypeMapping > ();
    }
    typeMappings.add(typeMapping);
  }
}


       TypeSet的初始化     在配置文件中配置流程引擎中需要使用的变量的类型

       Jbpm.defaut.cfg.xml引入变量类型配置的文件路径

< process-engine-context >
 
   
< repository-service />
   
< repository-cache />
   
< execution-service />
   
< history-service />
   
< management-service />
   
< identity-service />
   
< task-service />

   
< object class ="org.jbpm.pvm.internal.id.DatabaseDbidGenerator" >
     
< field name ="commandService" >< ref object ="newTxRequiredCommandService" /></ field >
   
</ object >

   
< object class ="org.jbpm.pvm.internal.id.DatabaseIdComposer" init ="eager" />
   
   
< object class ="org.jbpm.pvm.internal.el.JbpmElFactoryImpl" />
   
<!-- 定义变量配置文件的路径 -->
   
< types resource ="jbpm.variable.types.xml" />

   
< address-resolver />

 
</ process-engine-context >

 

       Jbpm.variable.types.xml定义了变量的类型、使用的转换器等信息

 

< types >

  
<!--  types stored in a native column  -->
  
< type  name ="string"  class ="java.lang.String"  variable-class ="org.jbpm.pvm.internal.type.variable.StringVariable"   />
  
< type  name ="long"    class ="java.lang.Long"  variable-class ="org.jbpm.pvm.internal.type.variable.LongVariable"   />
  
< type  name ="double"  class ="java.lang.Double"  variable-class ="org.jbpm.pvm.internal.type.variable.DoubleVariable"   />

  
<!--  types converted to a string  -->
  
< type  name ="date"     class ="java.util.Date"  converter ="org.jbpm.pvm.internal.type.converter.DateToStringConverter"  variable-class ="org.jbpm.pvm.internal.type.variable.StringVariable"   />
  
< type  name ="boolean"  class ="java.lang.Boolean"  converter ="org.jbpm.pvm.internal.type.converter.BooleanToStringConverter"  variable-class ="org.jbpm.pvm.internal.type.variable.StringVariable"   />
  
< type  name ="char"     class ="java.lang.Character"  converter ="org.jbpm.pvm.internal.type.converter.CharacterToStringConverter"  variable-class ="org.jbpm.pvm.internal.type.variable.StringVariable"   />

  
<!--  types converted to a long  -->
  
< type  name ="byte"     class ="java.lang.Byte"  converter ="org.jbpm.pvm.internal.type.converter.ByteToLongConverter"  variable-class ="org.jbpm.pvm.internal.type.variable.LongVariable"   />
  
< type  name ="short"    class ="java.lang.Short"  converter ="org.jbpm.pvm.internal.type.converter.ShortToLongConverter"  variable-class ="org.jbpm.pvm.internal.type.variable.LongVariable"   />
  
< type  name ="integer"  class ="java.lang.Integer"  converter ="org.jbpm.pvm.internal.type.converter.IntegerToLongConverter"  variable-class ="org.jbpm.pvm.internal.type.variable.LongVariable"   />

  
<!--  types converted to a double  -->
  
< type  name ="float"  class ="java.lang.Float"  converter ="org.jbpm.pvm.internal.type.converter.FloatToDoubleConverter"  variable-class ="org.jbpm.pvm.internal.type.variable.DoubleVariable"   />

  
<!--  byte[] and char[]  -->
  
< type  name ="byte[]"  class ="[B"  variable-class ="org.jbpm.pvm.internal.type.variable.BlobVariable"   />
  
< type  name ="char[]"  class ="[C"  variable-class ="org.jbpm.pvm.internal.type.variable.TextVariable"   />

  
< type  name ="hibernate-long-id"    class ="hibernatable"  id-type ="long"  variable-class ="org.jbpm.pvm.internal.type.variable.HibernateLongVariable"   />
  
< type  name ="hibernate-string-id"  class ="hibernatable"  id-type ="string"  variable-class ="org.jbpm.pvm.internal.type.variable.HibernateStringVariable"   />

  
< type  name ="serializable"  class ="serializable"  converter ="org.jbpm.pvm.internal.type.converter.SerializableToBytesConverter"  variable-class ="org.jbpm.pvm.internal.type.variable.BlobVariable"   />

  
<!--  TODO: add ejb3 entity bean support  -->
  
<!--  TODO: add JCR activity support  -->
  
<!--  TODO: add collection support  -->
  
</ types >

 

         TypesBinding解析jbpm.variable.types.xml中的变量类型定义        

 

public   class  TypesBinding  extends  WireDescriptorBinding {

  
public  TypesBinding() {
    
super ( " types " );
  }

  
public  Object parse(Element element, Parse parse, Parser parser) {
    StreamInput streamSource 
=   null ;
    
// 查找type文件    
     if  (element.hasAttribute( " file " )) {
      String fileName 
=  element.getAttribute( " file " );
      File file 
=   new  File(fileName);
      
if  (file.exists()  &&  file.isFile()) {
        streamSource 
=   new  FileStreamInput(file);
        parser.importStream(streamSource, element, parse);
      } 
else  {
        parse.addProblem(
" file  " + fileName + "  isn't a file " , element);
      }
    }

    
if  (element.hasAttribute( " resource " )) {
      String resource 
=  element.getAttribute( " resource " );
      ClassLoader classLoader 
=  Thread.currentThread().getContextClassLoader();
      streamSource 
=   new  ResourceStreamInput(resource, classLoader);
      parser.importStream(streamSource, element, parse);
    }

    
if  (element.hasAttribute( " url " )) {
      String urlText 
=  element.getAttribute( " url " );
      
try  {
        URL url 
=   new  URL(urlText);
        streamSource 
=   new  UrlStreamInput(url);
        parser.importStream(streamSource, element, parse);
      } 
catch  (Exception e) {
        parse.addProblem(
" couldn't open url  " + urlText, e);
      }
    }

    TypesDescriptor typesDescriptor 
=   new  TypesDescriptor();

    List
< Element >  typeElements  =  XmlUtil.elements(element,  " type " );
    
for  (Element typeElement: typeElements) {
      TypeMapping typeMapping 
=  parseTypeMapping(typeElement, parse, parser);
      typesDescriptor.addTypeMapping(typeMapping);
    }
    
return  typesDescriptor;
  }

  
protected  TypeMapping parseTypeMapping(Element element, Parse parse, Parser parser) {
    TypeMapping typeMapping 
=   new  TypeMapping();
    Type type 
=   new  Type();
    typeMapping.setType(type);

    
//  type name
    
// 类型名称
     if  (element.hasAttribute( " name " )) {
      type.setName(element.getAttribute(
" name " ));
    }

    String hibernateSessionFactoryName 
=  XmlUtil.attribute(element,  " hibernate-session-factory " );

    
//  first we get the matcher
    Matcher matcher  =   null ;
    
if  (element.hasAttribute( " class " )) {
      String className 
=  element.getAttribute( " class " );

      
//  if type="serializable"
       if  ( " serializable " .equals(className)) {
        matcher 
=   new  SerializableMatcher();

      
//  if type="hibernatable"
      }  else   if  ( " hibernatable " .equals(className)) {
        
if  (element.hasAttribute( " id-type " )) {
          String idType 
=  element.getAttribute( " id-type " );
          
if  ( " long " .equalsIgnoreCase(idType)) {
            matcher 
=   new  HibernateLongIdMatcher(hibernateSessionFactoryName);
          } 
else   if  ( " string " .equalsIgnoreCase(idType)) {
            matcher 
=   new  HibernateStringIdMatcher(hibernateSessionFactoryName);
          } 
else  {
            parse.addProblem(
" id-type was not 'long' or 'string':  " + idType, element);
          }
        } 
else  {
          parse.addProblem(
" id-type is required in a persistable type " , element);
        }

      
//  otherwise, we expect type="some.java.ClassName"
      }  else  {
        matcher 
=   new  ClassNameMatcher(className);
      }

    } 
else  {
      
//  look for the matcher element
      Element matcherElement  =  XmlUtil.element(element,  " matcher " );
      Element matcherObjectElement 
=  XmlUtil.element(matcherElement);
      
if  (matcherObjectElement != null ) {
        
try  {
          Descriptor descriptor 
=  (Descriptor) parser.parseElement(matcherObjectElement, parse);
          matcher 
=  (Matcher) WireContext.create(descriptor);
        } 
catch  (ClassCastException e) {
          parse.addProblem(
" matcher is not a  " + Matcher. class .getName() + " " + (matcher != null   ?  matcher.getClass().getName() :  " null " ), element);
        }
      } 
else  {
        parse.addProblem(
" no matcher specified in  " + XmlUtil.toString(element), element);
      }
    }

    typeMapping.setMatcher(matcher);

    
//  parsing the converter
    Converter converter  =   null ;
    
if  (element.hasAttribute( " converter " )) {
      String converterClassName 
=  element.getAttribute( " converter " );
      
try  {
        Class
<?>  converterClass  =  ReflectUtil.classForName(converterClassName);
        converter 
=  (Converter) converterClass.newInstance();
      } 
catch  (Exception e) {
        parse.addProblem(
" couldn't instantiate converter  " + converterClassName, element);
      }
    } 
else  {
      
//  look for the matcher element
      Element converterElement  =  XmlUtil.element(element,  " converter " );
      Element converterObjectElement 
=  XmlUtil.element(converterElement);
      
if  (converterObjectElement != null ) {
        
try  {
          converter 
=  (Converter) parser.parseElement(converterObjectElement, parse);
        } 
catch  (ClassCastException e) {
          parse.addProblem(
" converter is not a  " + Converter. class .getName() + " " + (converter != null   ?  converter.getClass().getName() :  " null " ), element);
        }
      }
    }

    type.setConverter(converter);

    
//  parsing the variable class

    Class
<?>  variableClass  =   null ;
    
if  (element.hasAttribute( " variable-class " )) {
      String variableClassName 
=  element.getAttribute( " variable-class " );
      
try  {
        variableClass 
=  ReflectUtil.classForName(variableClassName);
      } 
catch  (Exception e) {
        parse.addProblem(
" couldn't instantiate variable-class  " + variableClassName, e);
      }
    } 
else  {
      parse.addProblem(
" variable-class is required on a type:  " + XmlUtil.toString(element), element);
    }

    type.setVariableClass(variableClass);

    
return  typeMapping;
  }
}

 

        TypeDescriptor用于运行时生成DefaultTypeSet

public class TypesDescriptor extends AbstractDescriptor {

  private static final long serialVersionUID = 1L;
  
  DefaultTypeSet defaultTypeSet = new DefaultTypeSet();
  
  public Object construct(WireContext wireContext) {
    return defaultTypeSet;
  }
  
  public Class
<  ?  >  getType(WireDefinition wireDefinition) {
    return DefaultTypeSet.class;
  }

  public void addTypeMapping(TypeMapping typeMapping) {
    defaultTypeSet.addTypeMapping(typeMapping);
  }
  
  public DefaultTypeSet getDefaultTypeSet() {
    return defaultTypeSet;
  }
}

 
        TypeMapping作为映射器,负责承载变量的类型和matcher

public   class  TypeMapping  implements  Serializable {

  Matcher matcher;
  Type type;

  
private   static   final   long  serialVersionUID  =   1L ;
  
  
public   boolean  matches(String name, Object value) {
    
return  matcher.matches(name, value);
  }
  
  
public  String toString() {
    
return   " ( " + matcher + " --> " + type + " ) " ;
  }
  
  
public   void  setMatcher(Matcher matcher) {
    
this .matcher  =  matcher;
  }
  
public  Type getType() {
    
return  type;
  }
  
public   void  setType(Type type) {
    
this .type  =  type;
  }
  
public  Matcher getMatcher() {
    
return  matcher;
  }
}

 

      Matcher,递归查询给定变量的类型以及所有的基类中是否有与该Matcher对应的类的变量类型相同的。

public   class  ClassNameMatcher  implements  Matcher {

  
private   static   final   long  serialVersionUID  =   1L ;
  
  String className 
=   null ;
  
  
public  ClassNameMatcher(String className) {
    
this .className  =  className;
  }
  
  
public  String toString() {
    
return  className;
  }

  
public   boolean  matches(String name, Object value) {
    
if  (value == null ) {
      
return   true ;
    }
    
    Class
<?>  valueClass  =  value.getClass();
    
    
while  (valueClass != null ) {
      
if  (className.equals(value.getClass().getName())) {
        
return   true ;
      } 
else  {
        Class
<?> [] interfaces  =  valueClass.getInterfaces();
        
for  ( int  i = 0 ; i < interfaces.length; i ++ ) {
          
if  (className.equals(interfaces[i].getName())) {
            
return   true ;
          }
        }
        valueClass 
=  valueClass.getSuperclass();
      }
    }
    
return   false ;
  }
}


        Type 定义变量类型的名称、转换器和对应的Variable

 

public   class  Type  implements  Serializable {

  
private   static   final   long  serialVersionUID  =   1L ;
  
  
protected  String name;
  
protected  Converter converter;
  
protected  Class <?>  variableClass;

  
public  String toString() {
    
if  (name != null ) {
      
return  name;
    }
    StringBuilder text 
=   new  StringBuilder();
    
if  (converter != null ) {
      text.append(converter.toString());
      text.append(
" --> " );
    }
    
if  (variableClass != null ) {
      text.append(variableClass.getSimpleName());
    } 
else  {
      text.append(
" undefined " );
    }
    
return  text.toString();
  }
  
  
public  Converter getConverter() {
    
return  converter;
  }
  
public   void  setConverter(Converter converter) {
    
this .converter  =  converter;
  }
  
public  Class <   ?   >  getVariableClass() {
    
return  variableClass;
  }
  
public   void  setVariableClass(Class <   ?   >  variableClass) {
    
this .variableClass  =  variableClass;
  }
  
public  String getName() {
    
return  name;
  }
  
public   void  setName(String name) {
    
this .name  =  name;
  }
}

 

       Converter,负责变量运行时的表现形式和持久化形式进行转化

public   class  SerializableToBytesConverter  implements  Converter {

  
private   static   final   long  serialVersionUID  =   1L ;
  
  
public   boolean  supports(Object value, ScopeInstanceImpl scopeInstance, Variable variable) {
    
if  (value == null return   true ;
    
return  Serializable. class .isAssignableFrom(value.getClass());
  }

  
public  Object convert(Object o, ScopeInstanceImpl scopeInstance, Variable variable) {
    
byte [] bytes  =   null ;
    
try  {
      ByteArrayOutputStream baos 
=   new  ByteArrayOutputStream(); 
      ObjectOutputStream oos 
=   new  ObjectOutputStream(baos);
      oos.writeObject(o);
      oos.flush();
      bytes 
=  baos.toByteArray();

      Transaction transaction 
=  EnvironmentImpl.getFromCurrent(Transaction. class false );
      
if  (transaction != null ) {
        transaction.registerDeserializedObject(
new  DeserializedObject(o, scopeInstance, (BlobVariable) variable));
      }
      
    } 
catch  (IOException e) {
      
throw   new  JbpmException( " couldn't serialize ' " + o + " ' " , e);
    }
    
    
return  bytes;
  }

  
public  Object revert(Object o, ScopeInstanceImpl scopeInstance, Variable variable) {
    
byte [] bytes  =  ( byte []) o;
    
try  {
      ByteArrayInputStream bais 
=   new  ByteArrayInputStream(bytes);

      ObjectInputStream ois 
=   null ;
     
      ois 
=   new  DeploymentObjectInputStream(bais, scopeInstance.getExecution().getProcessDefinition().getDeploymentId());
      
      Object object 
=  ois.readObject();
      
      Transaction transaction 
=  EnvironmentImpl.getFromCurrent(Transaction. class false );
      
if  (transaction != null ) {
        transaction.registerDeserializedObject(
new  DeserializedObject(object, scopeInstance, (BlobVariable) variable));
      }
      
      
return  object;

    } 
catch  (Exception e) {
      
throw   new  JbpmException( " couldn't deserialize object " , e);
    }
  }
}

 

        Variable,定义具体的变量以及一些持久化需要的属性

 

public   class  StringVariable  extends  Variable {
  
  
private   static   final   long  serialVersionUID  =   1L ;
  
  
protected  String string  =   null ;

  
public   boolean  isStorable(Object value) {
    
if  (value == null return   true ;
    
return  (String. class == value.getClass());
  }

  
public  Object getObject() {
    
return  string;
  }

  
public   void  setObject(Object value) {
    
this .string  =  (String) value;
    
if  (value != null ) {
      
this .textValue  =  string;
    } 
else  {
      
this .textValue  =   null ;
    }
  }
}

原文:http://www.cnblogs.com/wufengtinghai/archive/2011/07/17/2108551.html
分享到:
评论

相关推荐

    JBPM深入解析之变量设计

    【JBPM深入解析之变量设计】 JBPM,全称Java Business Process Management,是一款开源的工作流管理系统,用于构建灵活且可扩展的业务流程。它提供了一种模型化的方式来定义和执行业务流程,允许开发者通过编程或者...

    深入浅出jBPM.1-6章测试代码_jbpm-test.rar

    本篇文章将深入解析jBPM的1-6章测试代码,旨在帮助读者掌握jBPM的核心概念和实际操作。 1. **jBPM基本概念** - **流程定义**:jBPM通过BPMN 2.0模型来定义工作流程,包括任务、事件、决策等元素。 - **流程实例**...

    深入浅出JBPM

    配置方面,除了基本的配置工厂和属性设置外,还需要关注Hibernate配置、节点类型、动作类型、业务日历、变量映射、转换器、模型和流程包解析等配置文件,以及在JBoss中的日志配置,确保JBPM能够在特定的环境中正确...

    jbpm5源代码

    jbpm5的核心在于提供一个可扩展且灵活的业务流程管理平台,允许开发者设计、执行、管理和监控业务流程。以下是jbpm5源代码中涉及的一些关键知识点: 1. **工作流引擎**:jbpm5的核心是工作流引擎,它负责解析BPMN2...

    JBPM工作流程表结构关系解析文档下载

    **JBPM工作流程表结构关系解析** JBPM(Java Business Process Management)是一个开源的工作流管理系统,用于设计、执行和管理业务流程。它提供了一个全面的框架,允许开发者和业务分析师协同工作,构建灵活且可...

    jbpm4.4-demo

    在深入研究jbpm4.4-demo时,你将学习到如何使用jbpm提供的API和工作流服务,如流程实例的启动、任务的领取和完成、流程变量的获取和修改等。同时,你还会接触到如何利用jbpm的工作流引擎进行流程的动态改变和扩展,...

    JBPM4.4工作流数据表结构的详解

    本文将深入解析JBPM4.4中的主要数据表及其作用。 首先,`JBPM4_DEPLOYMENT`表是流程定义表,它存储了所有部署的流程模板的信息。其中,`DBID`是每个流程定义的唯一标识,`NAME`用于记录流程模版的名称,而`...

    JBPM4 java源代码分包详解JBPM4

    在深入研究JBPM4的源代码时,我们可以从其包结构中了解到框架的核心功能和设计理念。 1. **org.jbpm.pvm.internal.ant**: 此包包含与Ant构建工具集成的相关类,主要用于发布流程和辅助启动JBoss服务器的任务。这...

    深入浅出 jBPM 电子书.doc

    **深入浅出 jBPM:理解企业级工作流与业务流程管理** jBPM,全称为Java Business Process Management,是一款开源的工作流管理系统,由Red Hat公司维护,它提供了全面的BPM(Business Process Management)解决方案...

    jbpm3.2.2工作流入门例子

    jbpm是一款开源的工作流管理系统,它提供了一整套解决方案,用于设计、执行和管理业务流程。jbpm3.2.2是jbpm的一个版本,它在当时提供了许多关键功能,如流程定义、流程实例管理、任务管理和事件处理等。本入门例子...

    JBPM JAR包1

    首先,让我们深入了解一下JBPM的核心组件: 1. **流程定义语言(BPMN)**: JBPM支持Business Process Modeling Notation (BPMN) 2.0标准,这是一种图形化的流程建模语言,允许开发者以直观的方式定义复杂的业务流程...

    工作流jbpm应用的实例

    工作流jbpm应用实例解析 工作流jbpm(Java Business Process Management)是一种开源的工作流管理系统,主要用于设计、执行和管理业务流程。jbpm是基于Java技术的,它提供了丰富的API和图形化工具,使得开发者可以...

    jbpm中文指南(包括3和4的)

    通过阅读《jbpm中文指南》,开发者可以深入了解这两个版本的差异,以及如何在实际项目中选择和应用合适的jbpm版本。指南将详细解析每个版本的功能特性、配置方法和最佳实践,帮助读者从理论到实践全面掌握jbpm的使用...

    jbpm Java工作流 教程

    JBPM设计之初就考虑到了与Java环境的无缝集成,其API提供了丰富的功能,便于开发者在Java应用程序中嵌入工作流逻辑。例如: 1. **流程实例的启动**:通过调用JBPM API,可以在Java代码中启动一个流程实例。 2. **...

    jbpm3.1API

    在"jbpm3.1中文文档.chm"中,你将找到详细的API文档,包括方法说明、示例代码和使用指南,这对于深入理解和使用jbpm3.1 API至关重要。通过阅读和实践,你可以掌握如何利用jbpm3.1 API构建高效的工作流解决方案,满足...

    JBoss_jBPM_jPDL用户开发手册_3.2.3.pdf 中文-(转)zhangym

    - **jPDL语法详解**:深入解析jPDL的语法规则和使用技巧。 - **流程设计与执行**:介绍如何使用jBPM Designer创建流程图,以及在代码中启动和控制流程。 - **监听器与事件**:讲解如何利用监听器捕获流程中的事件,...

    jbpm工作流简单实例

    jbpm(Java Business Process Management)是一个开源的工作流管理系统,它提供了一整套解决方案,用于设计、执行和管理业务流程。jbpm不仅支持BPMN(Business Process Model and Notation)标准,还具备强大的规则...

Global site tag (gtag.js) - Google Analytics