前言
activiti是影响力比较大的工作流引擎之一。虽然近年来由于发展观念等原因导致开发人员分道扬镳,flowable和camunda的发展势头都很猛,尤其是camunda,很有可能独占未来工作流引擎的鳌头。比较可惜目前市面上关于工作流引擎的教程比较少,flowable和camunda就更少了。而工作流引擎中比较基础的用户api通常很难以满足中国式流程(撤回、跳转、加签等)需求,即入门级的使用或者在网上随便搜索一两个例子是无法解决实际工程的需要,这就导致了工作流引擎的上手极为困难。有幸拜读冀正、张志祥老师的《activiti权威指南》(干货满满的书)。对activiti的源码抽丝剥茧,加深了我对activiti的认识。也希望通过activiti的学习,对以后学习camunda有所帮助。为此对自己的学习进行记录和总结。
activiti的工作流的常用步骤大概有以下几个:
- 流程引擎初始化;
- 流程部署;
- 流程启动;
- 流程提交;
后面的文章打算把这些基本内容进行简单展示,然后再逐步对深入的知识进行一定剖析(到什么程度看我本人造化……)。本次以activiti5.22作为例子
activiti流程引擎的配置与初始化操作
首先新建一个maven项目,添加pom文件中添加:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.ly.myActiviti</groupId>
<artifactId>engineConfigure</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<activitiVersion>5.22.0</activitiVersion>
<log4jVersion>1.2.17</log4jVersion>
<mysql-connector.version>5.1.48</mysql-connector.version>
<slf4jVersion>1.7.25</slf4jVersion>
</properties>
<dependencies>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-engine</artifactId>
<version>${activitiVersion}</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring</artifactId>
<version>${activitiVersion}</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-bpmn-model</artifactId>
<version>${activitiVersion}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4jVersion}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql-connector.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4jVersion}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4jVersion}</version>
</dependency>
</dependencies>
</project>
添加log4j的配置文件log4j.properties到resource目录下,源码调试的时候还是相当有用的。需要跟踪源码的时候,只需要把log4j.rootLogger改成debug或者info等级,会打印不少调试信息。
### set log levels ###
log4j.rootLogger = error , stdout
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = logs/error.log \#\# \u5F02\u5E38\u65E5\u5FD7\u6587\u4EF6\u540D
log4j.appender.D.Append = true
log4j.appender.D.Threshold = ERROR \#\# \u53EA\u8F93\u51FAERROR\u7EA7\u522B\u4EE5\u4E0A\u7684\u65E5\u5FD7\!\!\!
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
然后要添加activiti的配置文件activiti.cfg.xml到resource目录下面
<?xml version="1.0" encoding="UTF-8"?>
<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">
<bean id="processEngineConfiguration"
class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
<property name="jdbcUrl"
value="jdbc:mysql://localhost:3306/db_activiti?useUnicode=true&&characterEncoding=utf8&serverTimezone=UTC" />
<property name="jdbcDriver" value="com.mysql.jdbc.Driver" />
<property name="jdbcUsername" value="root" />
<property name="jdbcPassword" value="" />
<property name="databaseSchemaUpdate" value="true" />
</bean>
</beans>
可以看到,这里的配置文件主要是数据库连接的配置。其实activiti的扩展性非常强,自定义的解析器、拦截器等等都可以配置到其中。
扩展:
databaseSchemaUpdate可以有以下几个值,大致的意思是:
- true:流程引擎启动时对所有表进行更新操作,如果数据库不存在表,则会新建;
- false(默认):启动时会从act_ge_property表中查询版本与当前的版本是否匹配,就是数据库中的schema.version和程序的ProcessEngine.VERSION字段是否相等。不匹配则抛出异常;
- create-drop:流程引擎启动时创建表,关闭时删除表;
- drop-create:流程引擎启动时先删除原来存在的表,重新创建;
- create:流程引擎启动时不管数据库是否存在表,都进行新建。如果库中已存在表,可能导致新建错误。
因此后面三种都不太常使用。
接下来要在数据库中新建一个库。这里新建一个名为“db_activiti”的库,和activiti.cfg.xml里面的连接对应。之后编写主程序App.java测试结果
package engineConfigure;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.ProcessEngineConfiguration;
public class App {
private ProcessEngine pe;
//使用ProcessEngineConfiguration进行构建
public void getFromProcessEngineConfiguration() {
ProcessEngineConfiguration pec = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
pe = pec.buildProcessEngine();
}
//默认构建
public void getDefaultProcessEngine() {
pe = ProcessEngines.getDefaultProcessEngine();
}
public static void main(String[] args) {
App app = new App();
app.getFromProcessEngineConfiguration();
}
}
无论通过ProcessEngineConfiguration构建,还是通过默认方式构建,成功后你都会看到activiti在“db_activiti”库里面新建了属于它自己的表。这样就算完成了工作流引擎的初始化工作。下一步要做的是部署流程。
这里的默认构建方式,其源码也是调用ProcessEngineConfiguration进行构建。默认构建方式读取的是默认路径下的activiti.cfg.xml,所以如果你的activiti配置文件不在默认路径下,或者名称不是“activiti.cfg.xml”,那么默认构建方式就读不到。比较灵活的话还是采取ProcessEngineConfiguration来进行构建。
ProcessEngineConfiguration是流程引擎的一个配置类,里面包含了流程引擎配置的大量参数,有很多setter和getter方法。因此除了通过xml进行配置,也可以通过编程式的方式去配置,进而构建流程引擎。如下:
ProcessEngineConfiguration pec = ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration()
.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_FALSE)
.setJdbcDriver("jdbc.driver")
.setJdbcUrl("jdbc.url")
.setJdbcUsername("jdbc.username")
.setJdbcPassword("jdbc.password")
.setJdbcMaxActiveConnections(200)
.setJdbcMaxIdleConnections(20)
.setJdbcMaxCheckoutTime(20000)
.setJdbcPingEnabled(true)
.setJdbcPingConnectionNotUsedFor(3600 * 1000)
.setJobExecutorActivate(false);
pe = pec.buildProcessEngine();