创建一个简单的工作流引擎,需要准备:数据库、工作流文件(BPMN)。创建工作流的基本流程: 构建 ProcessEngineConfiguration 对象 –> 设置数据库连接 –> 设置数据库表创建属性 –> 构建一个流程引擎。其中:ProcessEngineConfiguration 对象,是构建一个简单工作流的核心 API。
为了简单的示例操作,使用 Junit 创建测试用例创建即可。
创建简单的工作流引擎
创建工作流引擎的三个方法:
- 使用 ProcessEngineConfiguration 硬编码配置数据库连接创建
- 使用 ProcessEngineConfiguration + activiti.cfg.xml 文件创建
- 使用 ProcessEngines 默认配置创建
使用 ProcessEngineConfiguration 创建
使用 ProcessEngineConfiguration 创建工作流引擎时,需要指定好数据库、库表创建策略等
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration();
configuration.setJdbcDriver("com.mysql.jdbc.Driver"); configuration.setJdbcUrl("jdbc:mysql:///activiti?createDatabaseIfNotExist=true&useUnicode=true&charsetEncoding=utf8&serverTimezone=Hongkong"); configuration.setJdbcUsername("root"); configuration.setJdbcPassword("123456");
configuration.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
processEngine = configuration.buildProcessEngine(); System.out.println("流程创建成功");
|
使用 ProcessEngineConfiguration + activiti.cfg.xml 文件创建
此种创建方式,实际上是将数据库的链接配置,设置在了 xml 文件中。
activiti.cfg.xml 文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <?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:///activiti?createDatabaseIfNotExist=true&useUnicode=true&charsetEncoding=utf8&serverTimezone=Hongkong" /> <property name="jdbcDriver" value="com.mysql.jdbc.Driver" /> <property name="jdbcUsername" value="root" /> <property name="jdbcPassword" value="123456" /> <property name="databaseSchemaUpdate" value="true" /> </bean> </beans>
|
代码示例
1 2 3
| ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml"); processEngine = configuration.buildProcessEngine(); System.out.println("流程创建成功");
|
使用 ProcessEngines 默认配置创建
使用 ProcessEngines 默认配置,实际上和 使用 xml 配置是一样的,因为使用 ProcessEngines 时会默认读取 activiti.cfg.xml 文件
1 2
| processEngine = ProcessEngines.getDefaultProcessEngine(); System.out.println("流程创建成功");
|
ProcessEngines 重点源码分析:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
| ProcessEngines.getDefaultProcessEngine();
public static ProcessEngine getDefaultProcessEngine() { return getProcessEngine("default"); }
public static boolean isInitialized() { return isInitialized; }
public static ProcessEngine getProcessEngine(String processEngineName) { if (!isInitialized()) { init(); } return processEngines.get(processEngineName); }
public synchronized static void init() { if (!isInitialized()) { if (processEngines == null) { processEngines = new HashMap<String, ProcessEngine>(); } ClassLoader classLoader = ReflectUtil.getClassLoader(); Enumeration<URL> resources = null; try { resources = classLoader.getResources("activiti.cfg.xml"); } catch (IOException e) { throw new ActivitiIllegalArgumentException("problem retrieving activiti.cfg.xml resources on the classpath: " + System.getProperty("java.class.path"), e); }
Set<URL> configUrls = new HashSet<URL>(); while (resources.hasMoreElements()) { configUrls.add(resources.nextElement()); } for (Iterator<URL> iterator = configUrls.iterator(); iterator.hasNext();) { URL resource = iterator.next(); log.info("Initializing process engine using configuration '{}'", resource.toString()); initProcessEngineFromResource(resource); }
try { resources = classLoader.getResources("activiti-context.xml"); } catch (IOException e) { throw new ActivitiIllegalArgumentException("problem retrieving activiti-context.xml resources on the classpath: " + System.getProperty("java.class.path"), e); } while (resources.hasMoreElements()) { URL resource = resources.nextElement(); log.info("Initializing process engine using Spring configuration '{}'", resource.toString()); initProcessEngineFromSpringResource(resource); }
setInitialized(true); } else { log.info("Process engines already initialized"); } }
|
部署一个简单的工作流
在创建工作流成功,并且创建 BPMN 文件后,可以进行流程的部署。流程部署需要用到仓库服务
,即 RepositoryService
部署操作代码示例
1 2 3 4 5 6 7 8 9
| RepositoryService repositoryService = processEngine.getRepositoryService();
Deployment deploy = repositoryService.createDeployment() .addClasspathResource("LevelBill.bpmn") .name("LevelBill:请假单流程") .category("办公类别") .deploy(); System.out.println("部署成功后返回的 id:" + deploy.getId() + ",部署的名称:" + deploy.getName());
|
查看部署结果
bpmn 文件:
1
| <process id="levelBill" isClosed="false" isExecutable="true" name="LevelBill" processType="None">
|
其中: KEY_
指向 BPMN 文件中 的 id, NAME_
指向 BPMN 文件中的 name,_DEPLOYMENT_ID_
指向 act_re_deployment 表的 id,RESOURCE_NAME_
指向 构建 deploy 时的 classpathResource 的值
其中:next.dbid 的值VALUE_
即为下一步运行部署操作时,act_re_deployment
的 id。
再次运行部署操作
再次运行部署操作,查看 act_ge_property
和 act_re_deployment
表,可以看到 act_ge_property
的 next.dbid 的值变了,且 act_re_deployment
的中 id 变为上一次运行后 act_ge_property
的 next.dbid 的值。