1. Quick Start
1.1 使用Activiti的前置要求
- Java 7及以上的运行时环境。
- Apache Tomcat(官方说明:因为仅依赖了Servlet功能,任意web容器应该都可以运行)。
1.2 一分钟启动Demo——使用默认配置的Activiti UI
-
复制从官网下载的activiti-app.war到Tomcat的webapps目录下。
-
运行bin目录下startup.bat或startup.sh来启动Tomcat。
-
Tomcat启动后,从浏览器中访问http://localhost:8080/activiti-app,使用用户名admin和密码test登入。
【 一些关于Activiti UI应用的特别说明】
(1) 该demo默认使用一个内存数据库(in-memory database)H2。可以修改WEB-INF/classes/META-INF/activiti-app/activiti-app.properties中的配置,使该demo运行在一个独立的H2或者其他数据库上。
(2) Activiti只是一个jar包,可以被嵌入到人和Java环境中(如结合swing或在Tomcat、JBoss、WebSphere等容器上运行),或者可以将Activiti作为一个典型的、独立的BPM(业务流程管理)服务器运行。H2 是一个用 Java 开发的嵌入式数据库,它本身只是一个类库,即只有一个 jar 文件,可以直接嵌入到应用项目中。
2. 配置
2.1 创建一个ProcessEngine(核心)
2.2.1 使用默认配置文件classpath:avtiviti.cfg.xml和ProcessEngines类来获取一个ProcessEngine:
- 在类路径下的一个名为activiti.cfg.xml的配置文件中配置Activiti处理引擎。(注意:如果使用Spring的方式来构造一个ProcessEngine,该配置方式不可用。)
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <!-- 1. 必须包含一个id为processEnineConfigurtion的bean(id是固定的); 根据环境的不同,目前可以选择四种不同的实现,它们都有与环境对应的默认配置: StandaloneProcessEngineConfiguration:该配置下处理引擎以standalone方式运行,Activiti来处理事务。默认情况下,只有引擎启动时才会检查数据库,如果没有Activiti schema定义或者schema版本不正确将会抛出异常。 StandaloneInMemProcessEngineConfiguration:出于单元测试目的使用的类,因为默认使用的内存数据库H2随引擎的启动/停止而创建/删除,一般不会使用。 SpringProcessEngineConfiguration:当在Spring环境中使用处理引擎的情况下配置该类。 JtaProcessEngineConfiguration:当引擎以standalone模式运行且使用JTA事务的情况下配置该类。 --> <bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration"> <!-- 2. 配置Activiti引擎使用的数据源的两种方式: 2.1 直接配置JDBC属性 <property name="xxx" value="yyy"/>,这种方式使用的是MyBatis的默认连接池配置 2.2 引用之前的数据源 <property name="dataSource" ref="${XXXDataSourceId}"/>,可以是C3P0/DBCP/HAKARI/DRUID...,推荐(因为Mybatis的默认连接池在处理大量并发请求的场景下的效率和弹性都不是最优解)。 注意:Activiti并不会引入这些数据源所需的依赖,需要自己导入。 --> <property name="jdbcUrl" value="jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000" /> <property name="jdbcDriver" value="org.h2.Driver" /> <property name="jdbcUsername" value="sa" /> <property name="jdbcPassword" value="" /> <!-- 3. 可选的数据源配置 databaseSchemaUpdate允许设置在Activiti处理引擎启动和停止时对数据库schema的处理策略。 false(默认值),当处理引擎被创建时,参照库检查数据库schema的版本,如果版本不匹配则抛出异常。 true,在处理引擎构建过程中,将执行检查,并且在必要时更新schema。如果schema不存在,就创建。 create-drop,schema随着处理引擎的创建/关闭来创建/删除。 --> <property name="databaseSchemaUpdate" value="true" /> <property name="asyncExecutorActivate" value="false" /> <property name="mailServerHost" value="mail.my-corp.com" /> <property name="mailServerPort" value="5025" /> </bean> </beans>
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
2.1.2 通过编码的方式先构造ProcessEngineConfiguration,再来创建ProcessEngine
- 可以通过编码的方式,使用指定配置文件来创建ProcessEngineConfiguration对象,允许指定不同的id。
也可以完全不使用配置文件,创建一个基于默认值的ProcessEngineConfiguration。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") .setAsyncExecutorActivate(false) .buildProcessEngine();
2.2 Activiti的数据库表
2.2.1 创建Activiti专用的数据库表
- 为数据库创建表的最快捷的方式:
(1) 将activiti-engine的相关jar包添加到类路径下;
(2) 添加合适的数据库驱动;
(3) 在类路径下添加Activiti配置文件(activiti.cfg.xml),配置使用的数据库。
(4) 运行 DbSchemaCreate类的main方法。 - 与DDL相关的.sql脚本在activiti-engine.jar中,位于org.activiti.db.create/drop包下,这些文件的命名模式是:
(1) db是h2/mysql(5.6.4+版本是必要的)/oracle/postgres/db2/mssql中的任意一种。activiti.{db}.{create|drop}.{type}.sql
(2) type可选值有engine/identity/history可选值 意义 engine 必要。引擎执行需要的表结构。 identity 该类表包含了用户、组以及用户于组的成员关系。这类表是可选的,并且当使用默认权限管理时应该使用。 history 这类表包含了历史和检查信息。这类表市可选的:当历史登记设置为none时不需要。注意,这也会禁用一些在历史数据库中存储数据的特性。
注意:对于Activiti表结构已经创建或升级,之后又要升级MySQL数据库的情况(升级到5.6.4+,低于5.6.4的MySQL不支持毫秒精度),必须手动对列的类型更改。
2.2.2 Activiti数据库表的命名解释
Activiti使用的数据库名全部以"ACT_"开头,第二部分是一个“两字符”的标识,象征了表的用处。这个标识与Activiti service API也严格匹配。
(1) ACT_RE_*:RE代表了repository。这类表包含的是静态信息,如流程定义(process definitions)和流程资源(process resources,图片、规则等)。
(2) ACT_RU_*:RU代表了runtime。这类表包含了流程实例(process instance)运行时中的中间数据,当流程实例停止后,其对应的记录会从该表移除。这样就保证了runtime类表又小又快。
(3) ACT_ID_*:ID代表了identity。这类表包含了用户或组的实体身份信息。
(4) ACT_HI_*:HI代表了history。这类表包含了历史数据,如之前的过程实例、变量、任务等。
(5) ACT_GE_*:GE代表了general。这类表包含了各种情况下使用的数据。
2.2.3 对Acticiti数据库升级
- 在进行一次升级前,确保对数据库备份。
- 默认地,每次创建一个处理引擎时,都会进行一次版本检查。这通常在你的应用或者Activiti webapps启动时进行一次。如果Activiti类库发现类库的版本与Activiti数据库表的版本存在差异,将会抛出异常。
- 具体的升级步骤在遇到实际的场景后再进行整理。
2.3 Job Executor的配置
-
Activiti 5中的异步执行器(async executor)是Activiti 6中唯一可用的任务执行器。(因为在Activiti处理引擎中,这种异步任务的执行方式性能更高且对数据库更友好)Activiti 5中旧任务执行器在新版本中被移除。
AsyncExecutor组件管理了一个线程池来触发计时器和其他异步任务。可以使用其他实现,比如使用一个消息队列。
-
如果运行在JavaEE 7环境下,可以使用满足JSR-236规定的ManagedAsyncJobExecutor,它允许容器管理线程。在配置文件中需要传递thread factory来启用它(The managed implementation fall back to their default counterparts if the thread factory is not specified):
<bean id="threadFactory" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiName" value="java:jboss/ee/concurrency/factory/default" /> </bean> <bean id="customJobExecutor" class="org.activiti.engine.impl.jobexecutor.ManagedAsyncJobExecutor"> <!-- ... --> <property name="threadFactory" ref="threadFactory" /> <!-- ... --> </bean>
-
激活Job Executor
默认地,AsyncExecutor没有被激活和启动。使用下面的配置可以使其与Activiti处理引擎一起启动。<property name="asyncExecutorActivate" value="true" />
2.4 邮件服务器的配置(有专门的章节)
邮件服务器的配置是可选的。Activiti支持在业务流程中发送邮件。与之前的邮件服务一样,必须配置一个合法的SMTP邮件服务器。
2.5 历史记录的配置(有专门的章节)
自定义历史记录存储的配置是可选的。Activiti允许用户调整影响处理引擎的历史记录功能的属性。
2.6 Exposing configuration beans in expressions and scripts
2.7 部署缓存的配置
- 由于流程定义(process definition)的数据不会改变,因此将流程定义全都缓存起来。这就避免了每次需要流程定义时去数据库中获取。默认地,这个缓存processDefinitionCache是没有限制的。
- 限制流程定义缓存的配置。
设置该属性将会使用一个LRU缓存(Hard Limit)替换掉默认的HashMap缓存。该属性的最佳value值取决于存储的流程定义的总量,以及运行时被所有运行时过程实例(runtime process instances)实际使用的数量。<property name="processDefinitionCacheLimit" value="10" />
- 允许使用自定义的缓存实现,必须实现org.activiti.engine.impl.persistence.deploy.DeploymentCache接口。
<property name="processDefinitionCache"> <bean class="org.activiti.MyCache" /> </property>
- 还有一组相似的属性knowledgeBaseCacheLimit和knowledgeBaseCache,用来配置rules缓存。只有在流程中使用到rules task时才需要配置。
2.8 日志配置
默认地,activiti-engine依赖没有引入任何SLF4J的日志实现依赖,因此会自动使用你在工程中导入的日志实现框架。
2.8.1 Mapped Diagnostic Context
Activiti支持SLF4J的Mapped Diagnostic Context特性。基础信息连同将要记录的内容一起传递给底层Logger:
- processDefinition Id -> mdcProcessDefinitionID
- processInstance Id -> mdcProcessInstanceID
- execution Id -> mdcExecutionId
默认地,这些信息都不会被记录,可以配置logger来为它们制定所需的显示格式。以log4j的配置为例:
log4j.appender.consoleAppender.layout.ConversionPattern=ProcessDefinitionId=%X{mdcProcessDefinitionID}
executionId=%X{mdcExecutionId} mdcProcessInstanceID=%X{mdcProcessInstanceID} mdcBusinessKey=%X{mdcBusinessKey} %m%n
当日志中包含需要实时检查的信息,如使用日志分析器时,非常有用。
2.9 事件处理器(这一部分暂时还没用到,先不整理,实现思想和作用与原生Web Listener是一样的)
Activiti引擎提供的事件机制允许你在引擎内发生各种事件时得到通知。
- 可以为特定类型的事件注册监听器,而不是在分发任何类型的事件时都得到通知。允许通过配置添加引擎级别事件监听器,使用API在运行时添加引擎级别事件监听器,或者为BPML XML中特定的过程定义(Process Definitions)添加监听器。
- 所有被分发的事件都是org.activiti.engine.delegate.event.ActivitiEvent的子类,它们exposes的事件信息有type,executionId,processInstanceId以及processDefinitionId。(根据事件出现的条件不同,某些事件还包含了额外的上下文信息)