搜档网
当前位置:搜档网 › Activiti UserGuide 脚

Activiti UserGuide 脚

Activiti Probe:管理员的管理控制台。 使用这个工具来看看配置是正确的初始化流程引擎,数据库表的内容。
Activiti Explorer:流程引擎用户控制台。 使用此工具来查看您的个人和候选人名单的任务和完成任务。
Activiti Modeler powered by Signavio:流程图设计工具
Activiti Cycle:流程模型格式转换查看工具
Activiti的KickStart:简易的流程定义和内部表单编辑器

activiti-engine-examples:使用Activiti最常见的设置:BPMN流程定义和数据库存储过程中执行和例子使API使用的持久性。
这个项目包含了Eclipse项目文件,一个Ant构建文件和一个Maven POM文件。 Ant构建文件是独立的Maven POM的。 这两个为您展示如何用 ant 和 maven 构建和部署流程作为您的生成过程的一部分。
activiti-spring-examples:说明了如何在Spring环境中使用Activiti Engine
activiti-groovy-examples:说明了使用groovy(可理解成java的升级版)所需要的 lib 和 一个使用 groovy 脚本 的流程例子
activiti-jpa-examples:说明了 lib 的依赖和在Activiti中使用JPA
activiti-cycle-examples:这是一个示例项目,展示了Activiti Cycle
activiti-modeler-examples:一个基于模型库的文件,模型库Activiti Modeler在demo.setup中被配置

——依赖库(Library dependencies)
libs.engine.runtime.txt :运行Activiti引擎时依赖的库。
libs.engine.runtime.test.txt :在 libs.engine.runtime.txt 运行测试时需要的库
libs.engine.runtime.feature.groovy.txt :在 libs.engine.runtime.txt 使用Groovy所需库。
libs.engine.runtime.txt :在 libs.engine.runtime.txt 使用JPA所需库。
libs.spring.runtime.txt :在Spring环境中运行Activiti Engine所需库。 (此名单包括库在 libs.engine.runtime.txt )
libs.spring.runtime.test.txt :在 libs.spring.runtime.txt Spring环境运行测试所需库
libs.cycle.runtime.test.txt , libs.webapp.rest.txt 和 libs.webapp.ui.txt :各个组件(cycle, rest webapp 和 UI webapps)如:Activiti Explorer, Activiti Probe 和 Activiti Cycle 所需库


第3章 配置(Configuration)

——创建引擎(Creating a ProcessEngine)
Activiti process engine 通过 activiti.cfg.xml 来配置。(注意:如果你使用 Spring 这将有所改变)
获得引擎最简单的方法是使用 org.activiti.engine.ProcessEngines 类:
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine()
这个方法会找到 activiti.cfg.xml 文件并通过它的配置来构造一个引擎。以下代码是配置文件的例子:
xmlns:xsi="https://www.sodocs.net/doc/715602995.html,/2001/XMLSchema-instance"
xsi:schemaLocation="https://www.sodocs.net/doc/715602995.html,/schema/beans https://www.sodocs.net/doc/715602995.html,/schema/beans/spring-beans.xsd">



















注意,此XML配置实际上是一个Spring的配置,但这并不代表Activiti只能在Spring环境中使用! 我们只是利用了Spring的内部建设的解析引擎和依赖注入

引擎的配置对象也能使用编程的方法调用配置文件。它也能使用不同的bean id(如第三个例子)
ProcessEngineConfiguration.createProcessEngineConfigurationFromResourceDefault();
ProcessEngineConfiguration.createProcessEngineConfigurationFromResource(String resource);
ProcessEngineConfiguration.createProcessEngineConfigurationFromResource(String resource, String beanName);
ProcessEngineConfiguration.createProcessEngineConfigurationFromInputStream(InputStream inputStream);
ProcessEngineConfiguration.createProcessEngineConfigurationFromInputStream(InputStream inputStream, String beanName);

也可以不使用配置文件,使用默认的配置
ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration();
ProcessEngineConfiguration.createStandaloneInMemProcessEngineConfiguration();

如果需要,所有的 ProcessEngineConfiguration.createXXX() 方法所返回的 ProcessEngineConfiguration 可以做进一步进行调整。 调用 buildProcessEngine() 操作, ProcessEngine 被会创建:
ProcessEngine processEngine = ProcessEngineConfiguration.createStandaloneInMemProcessEngineConfiguration()
.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_FALSE)
.setJdbcUrl("jdbc:h2:mem:my-own-db;DB_CLOSE_DELAY=1000")
.setJobExecutorActivate(true)
.buildProcessEngine();

——ProcessEngineConfiguration bean
activiti.cfg.xml 必须包含有 ID"processEngineConfiguration"的 bean

这个 bean 会被用来构造 ProcessEngine。可以有多个类可以用于定义processEngineConfiguration。这些类代表不同的环境,并设置相对应的默认值。这是匹配您环境的最好的做法,它能尽可能减少 engine 配置所需的属性。以下是当前可直接用的类:
org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration:这个流程引擎被用于单通道,Activiti将会维护这个事务。默认情况下,数据库将会在引擎启动(和在没有 Activiti 的架构或架构的版本不正确抛出异常时)时检查
org.activiti.engi

ne.impl.cfg.StandaloneInMemProcessEngineConfiguration:这个是便于单元学习用途
org.activiti.spring.SpringProcessEngineConfiguration:流程引擎在 Spring 环境中运行时使用
org.activiti.engine.impl.cfg.JtaProcessEngineConfiguration:引擎在单独模式下运行时和JTA事务一起使用

——数据库配置(Database configuration)
见原文档


第4章 Spring集成(Spring integration)

——ProcessEngineFactoryBean
ProcessEngine会作为 Spring bean 被配置。起点是 org.activiti.spring.ProcessEngineFactoryBean。这个 bean 会拿到流程引擎的配置并创建引擎。这也就代表所有的配置属性和 Spring 是一样的

...






——事务(Transactions)
以 spring 的例子 SpringTransactionIntegrationTest 来做说明,以下是例子中的配置文件SpringTransactionIntegrationTest-context.xml,里面包括了 dataSource,transactionManager,processEngine 和 Activiti Engine services 的配置
xmlns:context="https://www.sodocs.net/doc/715602995.html,/schema/context"
xmlns:tx="https://www.sodocs.net/doc/715602995.html,/schema/tx"
xmlns:xsi="https://www.sodocs.net/doc/715602995.html,/2001/XMLSchema-instance"
xsi:schemaLocation="https://www.sodocs.net/doc/715602995.html,/schema/beans https://www.sodocs.net/doc/715602995.html,/schema/beans/spring-beans.xsd
https://www.sodocs.net/doc/715602995.html,/schema/context https://www.sodocs.net/doc/715602995.html,/schema/context/spring-context-2.5.xsd
https://www.sodocs.net/doc/715602995.html,/schema/tx https://www.sodocs.net/doc/715602995.html,/schema/tx/spring-tx-3.0.xsd">





















="false" />












...
其余的 spring 配置文件(包含了 beans 和 配置 )我们会用在其它的例子

...









你可以用 xml 文件配置 spring 应用环境,然后如下调用
ClassPathXmlApplicationContext applicationContext =
new ClassPathXmlApplicationContext("org/activiti/examples/spring/SpringTransactionIntegrationTest-context.xml");
或用注解
@ContextConfiguration("classpath:org/activiti/spring/test/transaction/SpringTransactionIntegrationTest-context.xml")
进行完上面的步骤后我们就能得到 service beans 和 invoke 方法。ProcessEngineFactoryBean 会为 services 添加额外的拦截器,目的是请求 Activiti service 方法的 Propagation.REQUIRED 事务语法。以下我们用 respositoryService 的流程部署作为例子
RepositoryService repositoryService = (RepositoryService) applicationContext.getBean("repositoryService");
String deploymentId = repositoryService
.createDeployment()
.addClasspathResource("org/activiti/spring/test/hello.bpmn20.xml")
.deploy()
.getId();
其它方法也相同。在这个例子中,Spring 事务会环绕在 userBean.hello()方法 ,并且 Activiti service 方法调用的也会加入到事务中
UserBean userBean = (UserBean) applicationContext.getBean("userBean");
userBean.hello();
-------------------
public class UserBean {

/** injected by Spring */
private RuntimeService runtimeService;

@Transactional
public void hello() {
// here you can do transactional stuff in your domain model
// and it will be combined in the same transaction as
// the startProcessInstanceByKey to the Activiti RuntimeService
runtimeService.startProcessInstanceByKey("helloProcess");
}

public void setRuntimeService(RuntimeService runtimeService) {
this.runtimeService = runtimeService;
}
}

——表达式(Expressions)
用默认设置使用 ProcessEngineFactoryBean,所有的 BPMN 流程表达式也能“

看到” Spring beans。例子 SpringTransactionIntegrationTest hello.bpmn20.xml 展示了如何使用 UEL 方法拦截 Spring bean:















----------------------Printer
public class Printer {

public void printMessage() {
System.out.println("hello world");
}
}
----------------------spring bean 配置

...





——资源自动部署
在流程引擎配置中,你可以设置好资源。当引擎被实例化后,所有的资源都会被扫描并发布。它会过滤发布资源以防止重复部署。只有当资源被改变时,新的部署方案才会被发布到 Activiti 的数据库中。在 Spring 服务器经常重启时,这在大多数情况下是很有意义的

...








第5章 API

——引擎API
查文档

——web应用中的流程引擎(The process engine in a webapplication)
ProcessEngine 是一个线程安全的类,可以很容易地在多个线程中共享。以下代码实现一个简单的初始化和销毁一个Servlet环境流程引擎
public class ProcessEnginesServletContextListener implements ServletContextListener {

public void contextInitialized(ServletContextEvent servletContextEvent) {
ProcessEngines.init();
}

public void contextDestroyed(ServletContextEvent servletContextEvent) {
ProcessEngines.destroy();
}

}
contextInitialized会委托给 ProcessEngines.init()方法,它将在资源文件的类路径上寻找 activiti.cfg.xml ,并根据配置文件创建一个 ProcessEngines

获得引擎
ProcessEngines.getDefaultProcessEngine()

ProcessEngines.getProcessEngine("myName");

——PVM API(Process Virtual Machine API)
PVM API 公开流程虚拟机的 POJO 核心。研究它能很好地学习 Activiti 内部的工作。POJO API 也可以用来建立新的流程语言。如:
PvmProcessDefinition processDefinition = new ProcessDefinitionBuilder()
.createActivity("a")
.initial()
.behavior(new WaitState())
.transition("b")
.endActivity(

)
.createActivity("b")
.behavior(new WaitState())
.transition("c")
.endActivity()
.createActivity("c")
.behavior(new WaitState())
.endActivity()
.buildProcessDefinition();

PvmProcessInstance processInstance = processDefinition.createProcessInstance();
processInstance.start();

PvmExecution activityInstance = processInstance.findExecution("a");
assertNotNull(activityInstance);

activityInstance.signal(null, null);

activityInstance = processInstance.findExecution("b");
assertNotNull(activityInstance);

activityInstance.signal(null, null);

activityInstance = processInstance.findExecution("c");
assertNotNull(activityInstance);


——表达式(Expressions)
Activiti 使用 UEL 流程表达式。
表达式可以用于 Java Service tasks, Execution Listeners, Task Listeners 和 Conditional sequence flows

Value expression:解析为一个值。默认情况下,所有流程变量都可以使用,包括所有 spring-beans。此外, DelegateExecuteion 也能用在表达式中,并且能通过 name 访问执行。由于它是被暴露执行的,所有通过 name 执行的变量和 spring-beans 会被隐藏并且不能被用于表达式
${myVar}
${myBean.myProperty}

Method expression:调用一个方法,有(无)参数。当没有参数调用时,确保添加一个空括号在方法名后面。传递的参数可以是文字或表达式。如
${printer.print()}
${myBean.addNewOrder('orderName')}
${myBean.doSomething(myVar, execution)}

这些表达式支持 primitives,beans,lists,arrays 和 maps 类型
更具体的用法和例子,参照:Expressions in Spring,Java Service tasks,Execution Listeners,Task Listeners 或 Conditional sequence flows。


第6章 部署(Deployment)

——业务档案(Business archives)
所有业务档案都要包装才能发布。一个业务档案就是部署一个 Activiti Engine 的单元。业务档案基本上相当于一个 zip 文件。它可以是 BPMN 2.0 processes,task forms,rules 和 其它类型文件。通常业务档案就是资源的集合。

当一个业务档案被发布,它会为 BPMN 文件 a.bpmn20.xml 的扩展被扫描。所有这些档案会被解析和潜在包含多个流程定义。

注意:要使用的业务档案必须放在 activiti-engine 的 classpath 里

——Java 类
在流程实例开始时,流程里所有要使用的自定义类必须放在引擎的 classpath 里。但在发布流程定义到引擎时不一定需要把类放在 classpath 中。

当你使用 demo setup 并且你相添加自定义类。你需要添加一个包含了你的类的 jar 包到 activiti-rest web应用中库。

——通过Activiti Probe部署
见文档

——通过编程方式部署
部署业务文档例子:
String barFileName = "path/to/process-one.bar";
ZipInputStream inputStream = new ZipInputStream(new FileInputStream(barFileName));

repositoryService.createDeployment()
.name(

"process-one.bar")
.addZipInputStream(inputStream)
.deploy();

——通过ant部署
先定义 deploy-bar 任务。确保所有 jar 包都在正确的路径上














——发布流程定义
repositoryService.createDeployment()
.name("expense-process.bar")
.addClasspathResource("org/activiti/expenseProcess.bpmn20.xml")
.addClasspathResource("org/activiti/expenseProcess.png")
.deploy();
流程图能通过 API 检索:
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
.processDefinitionKey("expense")
.singleResult();

String diagramResourceName = processDefinition.getDiagramResourceName();
InputStream imageStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), diagramResourceName);


第7章 BPMN


activiti:expression="#{myService.doSomething()}"
activiti:resultVariable="myVar" />

In the example above, the result of the service execution (the return value of the 'doSomething()' method invocation on an object that
is made available under the name 'myService' either in the process variables or as a Spring bean) is set to the process variable
named 'myVar' after the service execution completes.


第8章 Forms

有两种方案:内建表单(Build-in form rendering) 和 扩展表单(external form rendering)
可使用${xxxx}取变量

——内建表单
最简单的方案。
目前 Activiti Explorer 只使用这种表单。
例子:varcationRequest business process
使用这种方案,所有的 form 文件必须被发布,程序如下:
Deployment deployment = repositoryService.createDeployment()
.addClasspathResource("org/activiti/examples/taskforms/VacationRequest.bpmn20.xml")
.addClasspathResource("org/activiti/examples/taskforms/approve.form")
.addClasspathResource("org/activiti/examples/taskforms/request.form")
.addClasspathResource("org/activiti/examples/taskforms/adjustRequest.form")
.deploy();
其它部署方法可以查 Deployment 章节

通过 activiti:formKey 属性指定 startEvents 和 userTasks 的表单(头定义 xmlns:activiti="https://www.sodocs.net/doc/715602995.html,/bpmn")
activiti:formKey="org/activiti/examples/taskforms/request.form" />



id="handleRequest" name="Handle vacation request"
activiti:formKey="org/activiti/examples/taskforms/approve.form" >

Vacation request by ${employeeName}

...


属性 activiti:formKey 可以包含任何可标识你的 form 的文本值,但推荐使用资源文件路径的形式来标识
以下是 form 文件例子代码:

Vacation Request



Employee Name:




Number of days:




First day of vacation:




Date of return to work:




Vacation pay requested
Vacation pay requested


Motivation:



隐藏文本域提供额外的信息给 Activiti Explorer 客户端应用。因此 javascript 可以用隐藏域并加强相应的输入框能为。如:指定一个输入日期类型的输入框,Activiti Explorer 会添加一个日期 picker。

变量名区分大小写。
默认的流程变量类型是 String。隐藏域使用变量名后面跟"_type"定义类型(也能应用在 HTML 输入框的变量中)

目前提供 String, Integer, Boolean, Date 类型。

隐藏域的输入变量名后跟"_required"能指定变量是必需的


使用 API提供的 FormService.getRenderedStartForm 获取表单
String FormService.getRenderedStartForm(String processDefinitionId)

使用 FormService.submitStartFormData 开始一个新的流程实例,properties 是用户在表单输入的值
ProcessDefinition FormService.submitStartFormData(String processDefinitionId, Map properties)

——外部表单
获取表单数据的方法,得到的对象继承 FormData 类,有关方法查 javadocs:
StartFormData FormService.getStartFormData(String processDefinitionId) 和 TaskFormdata FormService.getTaskFormData(String taskId).
提交表单数据的方法:
ProcessInstance FormService.submitStartFormData(String processDefinitionId, Map properties) 和 void FormService.submitStartFormData(String taskId, Map properties)
获取资源(表单)的方法:
String ProcessDefinition.getDeploymentId() 和 InputStream RepositoryService.getResourceAsStream(String deploymentId, String resourceName);
属性

ce.getStartFormData(String processDefinitionId).getFormKey() 和 String FormService.getTaskFormData(String taskId).getFormKey() 获取

——表单变量

默认情况下,内建表单不需要定义即可把相对应的属性流程变量相关联

获取流程变量的方法:
formService.getStartFormData(String processDefinitionId).getFormProperties()

所有提交的属性会作为流程变量被保存。即表单上添加一个输入框时,一个新的流程变量就会被保存。
属性会从流程变量中派生,但不会像流程变量那样被保存

例子:








属性 room 会被映射到流程变量 room (String型)
属性 duration 映射到流程变量 duration (Long型)
属性 speaker 映射到流程变量 SpeekerName。它只能在 TaskFormData 中使用。如果 speaker 被提交会抛异常,所以要设 readable="false"。属性 readable="false" 把属性从 FormData 中排除,但它依然会被提交
属性 street 映射到 java bean 的属性 street (String型)。属性 required="true" 代表此属性是必需的

form 属性类型:
string, long, enum, date

FormProperty 信息通过 List formService.getStartFormData(String processDefinitionId).getFormProperties() 和 List formService.getTaskFormData(String taskId).getFormProperties() 得到
public interface FormProperty {
/** the key used to submit the property in {@link FormService#submitStartFormData(String, java.util.Map)}
* or {@link FormService#submitTaskFormData(String, java.util.Map)} */
String getId();
/** the display label */
String getName();
/** one of the types defined in this interface like e.g. {@link #TYPE_STRING} */
FormType getType();
/** optional value that should be used to display in this property */
String getValue();
/** is this property read to be displayed in the form and made accessible with the methods
* {@link FormService#getStartFormData(String)} and {@link FormService#getTaskFormData(String)}. */
boolean isReadable();
/** is this property expected when a user submits the form? */
boolean isWritable();
/** is this property a required input field */
boolean isRequired();
}
例子:


name="Speaker"
variable="SpeakerName"
type="string" />

type="date"
datePattern="dd-MMM-yyyy" />










数据 pattern 信息通过 formProperty.getType().getInformation("datePattern") 拿到
enumeration values 信息通过 formProperty.getType().getInformation("values") 拿到

——动态分配任务





——————————————
public class MyAssignmentHandler implements TaskListener {

public void notify(DelegateTask delegateTask) {
// Execute custom identity lookups here

// and then for example call following methods:
delegateTask.setAssignee("kermit");
delegateTask.addCandidateUser("fozzie");
delegateTask.addCandidateGroup("management");
...
}

}