http://blog.csdn.net/zwk626542417/article/details/46594505

***********************************************

一、前言

在上一篇文章中我们将工作流的相关概念、activiti的前世今生、activiti与jbpm的比较进行学习,这篇文章我们正式进行activiti的学习,activiti的整个学习我们主要通过例子的形式来理解。今天我们主要是准备下activiti的环境,在数据库中创建activiti默认的23张表以及activiti核心对象ProcessEngine最后是一个activiti的简单demo。

二、环境准备

相关软件及版本:

jdk版本:Jdk1.8

IDE:eclipse

数据库:MySQL

Activiti:5.13

    eclipse中安装流程设计器插件:

eclipse打开help->install new software,单击add:

Name: Activiti BPMN2.0 designer

Location:http://activiti.org/designer/update/

进行安装即可。

    引入jar包:

${Activiti_HOME}/install/activiti-5.13/libs(activiti相关包)+mysql对应驱动包(mysql-connector-Java.jar)

jar包引入完毕后,我们环境就准备的差不多了,往下我们就该创建我们activiti数据库默认的表了。

三、创建activiti

在activiti中,相对于前身jbpm基础上又额外多了5张表,所有现在的activiti框架默认提供了23张表。所以第一步我们就来创建这23张表。

方法1:使用代码来创建activiti工作流的表

  1. 方法1:使用代码来创建activiti工作流的表
  2. // 使用代码创建工作流需要的23张表
  3. @Test
  4. public void createTable() {
  5. // 工作流引擎的全部配置
  6. ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration
  7. .createStandaloneProcessEngineConfiguration();
  8. // 链接数据的配置
  9. processEngineConfiguration.setJdbcDriver("com.mysql.jdbc.Driver");
  10. processEngineConfiguration
  11. .setJdbcUrl("jdbc:mysql://localhost:3306/activiti1?createDatabaseIfNotExist=true&useUnicode=true&characterEncoding=utf8");
  12. processEngineConfiguration.setJdbcUsername("root");
  13. processEngineConfiguration.setJdbcPassword("123456");
  14. /*
  15. * public static final String DB_SCHEMA_UPDATE_FALSE = "false";
  16. * 不能自动创建表,需要表存在 public static final String DB_SCHEMA_UPDATE_CREATE_DROP
  17. * = "create-drop"; 先删除表再创建表 public static final String
  18. * DB_SCHEMA_UPDATE_TRUE = "true";如果表不存在,自动创建表
  19. */
  20. //如果表不存在,自动创建表
  21. processEngineConfiguration
  22. .setDatabaseSchemaUpdate(processEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
  23. // 工作流的核心对象,ProcessEnginee对象
  24. ProcessEngine processEngine = processEngineConfiguration
  25. .buildProcessEngine();
  26. System.out.println(processEngine);
  27. }

代码执行完毕,我们通过navicat查看数据库会发现,创建了一个新的数据库activiti1,并且还有23张表。

方式2:使用配置文件来创建activiti的表

在类路径下创建Activiti.cfg.xml文件,文件内容为:

  1. <beans xmlns="http://www.springframework.org/schema/beans"
  2. xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  5. http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
  6. http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
  7. <bean id="processEngineConfiguration"
  8. class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
  9. <!-- 连接数据的配置 -->
  10. <property name="jdbcDriver" value="com.mysql.jdbc.Driver"></property>
  11. <property name="jdbcUrl"
  12. value="jdbc:mysql://localhost:3306/activiti1?createDatabaseIfNotExist=true&useUnicode=true&characterEncoding=utf8"></property>
  13. <property name="jdbcUsername" value="root"></property>
  14. <property name="jdbcPassword" value="123456"></property>
  15. <!-- 没有表创建表 -->
  16. <property name="databaseSchemaUpdate" value="true"></property>
  17. </bean>
  18. </beans>

通过代码来加载配置文件中内容:

  1. /**
  2. * 使用配置文件来创建数据库中的表
  3. */
  4. @Test
  5. public void createTable_2() {
  6. //通过让工作流引擎的全部配置对象来执行配置文件中的内容来创建流程引擎对象
  7. ProcessEngine processEngine = ProcessEngineConfiguration
  8. .createProcessEngineConfigurationFromResource(
  9. "activiti.cfg.xml").buildProcessEngine();
  10. System.out.println("processEngine" + processEngine);
  11. }

运行产生的结果与第一种是一样的,其中这一种通过配置文件的方式是用的是比第一种多的。

连接数据库url写法:

无论是通过代码还是通过xml文件来创建工作流的表,里面都涉及到一个知识点就是mysql的url的写法,我们进行下小结:

#autoReconnect当数据库连接丢失时是否自动连接,取值true/false 缺省为false

#maxReconnects如果autoReconnect为true,此参数为重试次数,缺省为3次

#initialTimeout如果autoReconnect为true,此参数为重新连接前等待的秒数缺省为2

#maxRows设置查询时返回的行数,0表示全部缺省为0

#useUnicode是否使用unicode输出,true/false缺省为false

#characterEncoding如果useUnicode,该参数制定encoding类型,建议使用utf8缺省为无

#createDatabaseIfNotExist当JDBC连接指定数据库,如果此数据库不存在,此参数值为true时,则自动创建此数据库

下面是一个url的例子:

  1. jdbc:mysql://localhost:3306/ourmysql?
  2. createDatabaseIfNotExist=true&
  3. amp;useUnicode=true&
  4. amp;characterEncoding=utf8&
  5. amp;autoReconnect=true&
  6. amp;useLocalSessionState=true

四、核心对象ProcessEngine

数据库里的表创建完毕,接下来我们讲述activiti里面的核心对象ProcessEngine。

ProcessEngine类,一般称为流程引擎类,没错,这个流程引擎就是我们上一篇文章中提到的流程引擎,它是activiti中最核心的类,并且这个类是线程安全的,所有的线程和请求都可以使用同一个ProcessEngine对象,其它常用类几乎也都是由它而来的。

得到ProcessEngine对象:

    方式1:使用classpath根目录下的默认配置文件jbpm.cfg.xml创建一个单例的ProcessEngine

  1. ProcessEngineprocessEngine = ProcessEngines.getDefaultProcessEngine();

方式2:指定其他位置:配置文件,如src根目录config包下的my-jbpm-cfg.xml。

  1. ProcessEngineprocessEngine = ProcessEngineConfiguration
  2. .createProcessEngineConfigurationFromResource(
  3. "config/my-jbpm-cfg.xml").buildProcessEngine();

得到各个Service

RepositoryService

RepositoryService是管理流程定义的仓库服务的接口。

  1. RepositoryServicerepositoryService = processEngine.getRepositoryService();

RuntimeService

RuntimeService是activiti的流程执行服务类。可以从这个服务类中获取很多关于流程执行相关的信息,如执行管理,包括启动、推进、删除流程实例等操作。

  1. RuntimeServiceruntimeService = processEngine.getRuntimeService();

TaskService

TaskService是activiti的任务服务类。可以从这个类中获取任务的信息。

  1. TaskServicetaskservice = processEngine.getTaskService();

HistoryService

HistoryService 是activiti的查询历史信息的类。在一个流程执行完成后,这个对象为我们提供查询历史信息。

  1. HistoryServicehistoryService = processEngine.getHistoryService();

到这里关于activiti核心对象ProcessEngine先介绍这么多,下面看我们的小的helloworld的demo。

五、Demo流程

第一步流程设计画出业务流程

我们通过流程设计器就可以拖拖拽拽出我们的流程,同时设置相关属性,保存后会生成两个文件,分别是helloworld.bpmn和helloworld.png.

这是我们的流程图:

第二步部署流程定义

  1. /**
  2. * 部署流程定义
  3. */
  4. @Test
  5. public void deploymentProcessDefinition() {
  6. //创建核心引擎对象
  7. ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
  8. Deployment deployment = processEngine.getRepositoryService()// 与流程定义和部署对象相关的service
  9. .createDeployment()// 创建一个部署对象
  10. .name("helloworld入门程序")// 添加部署的名称
  11. .addClasspathResource("diagrams/helloworld.bpmn")// classpath的资源中加载,一次只能加载
  12. // 一个文件
  13. .addClasspathResource("diagrams/helloworld.png")// classpath的资源中加载,一次只能加载
  14. // 一个文件
  15. .deploy();// 完成部署
  16. System.out.println("部署ID:" + deployment.getId());
  17. System.out.println("部署名称:" + deployment.getName());
  18. }

运行结果:

部署ID:1

部署名称:helloworld入门程序

第三步
启动流程实例

  1. /**
  2. * 启动流程实例
  3. */
  4. @Test
  5. public void startProcessInstance() {
  6. // 流程定义的key
  7. String processDefinitionKey = "HelloWorld";
  8. ProcessInstance pi = processEngine.getRuntimeService()// 于正在执行的流程实例和执行对象相关的Service
  9. .startProcessInstanceByKey(processDefinitionKey);// 使用流程定义的key启动流程实例,key对应hellworld.bpmn文件中id的属性值,使用key值启动,默认是按照最新版本的流程定义启动
  10. System.out.println("流程实例ID:" + pi.getId());// 流程实例ID 101
  11. System.out.println("流程定义ID:" + pi.getProcessDefinitionId()); // 流程定义ID HelloWorld:1:4

运行结果为:

流程实例ID:101

流程定义ID:HelloWorld:1:4

第四步查询当前办理人的个人任务

  1. /**
  2. * 查询当前人的个人任务
  3. */
  4. @Test
  5. public void findMyPersonTask() {
  6. String assignee = "张三";
  7. List<Task> list = processEngine.getTaskService()// 与正在执行的认为管理相关的Service
  8. .createTaskQuery()// 创建任务查询对象
  9. .taskAssignee(assignee)// 指定个人认为查询,指定办理人
  10. .list();
  11. if (list != null && list.size() > 0) {
  12. for (Task task:list) {
  13. System.out.println("任务ID:"+task.getId());
  14. System.out.println("任务名称:"+task.getName());
  15. System.out.println("任务的创建时间"+task);
  16. System.out.println("任务的办理人:"+task.getAssignee());
  17. System.out.println("流程实例ID:"+task.getProcessInstanceId());
  18. System.out.println("执行对象ID:"+task.getExecutionId());
  19. System.out.println("流程定义ID:"+task.getProcessDefinitionId());
  20. System.out.println("#################################");
  21. }
  22. }
  23. }

运行结果:

任务ID:104

任务名称:提交申请

任务的创建时间Task[id=104,name=提交申请]

任务的办理人:张三

流程实例ID:101

执行对象ID:101

流程定义ID:HelloWorld:1:4

#################################

第五步
完成任务

  1. /**
  2. * 完成我的任务
  3. */
  4. @Test
  5. public void completeMyPersonTask(){
  6. //任务Id
  7. String taskId="104";
  8. processEngine.getTaskService()//与正在执行的认为管理相关的Service
  9. .complete(taskId);
  10. System.out.println("完成任务:任务ID:"+taskId);
  11. }

运行结果:

完成任务:任务ID:104

到这里我们就完成了一个简单的helloworld,从画一个流程图、到部署流程定义、启动流程实例、查询当前办理人的任务、完成当前的任务,从第二步开始每一步在数据库中都会有相应的记录进行添加、删除、更新,我们运行产生的结果也都是从数据库中查出来的记录,关于每一步对应与数据库中怎样的变化,我们会在后续的文章继续介绍。

六、后记

我们本篇文章主要讲述了activiti的环境准备包含各个软件的版本和安装流程设计器,接下来我们讲解了两种方式来创建activiti的23张表,还夹杂着一个数据库连接url的写法,接下来是activiti核心对象ProcessEngine,以及通过ProcessEngine获取相关的Service,最后通过一个特别简单的小demo来让大家对部署流程定义、启动流程实例、查询当前任务、完成当前任务这些步骤有一个感性的认识,详细的内容我们会在后续文章继续介绍。

工作流学习——Activiti整体认识二步曲 (zhuan)的更多相关文章

  1. 工作流学习——Activiti流程变量五步曲 (zhuan)

    http://blog.csdn.net/zwk626542417/article/details/46648139 ***************************************** ...

  2. 工作流学习——Activiti流程变量五步曲

    一.前言 上一篇文章我们将流程实例的启动与查询,任务的办理查询都进行了介绍,我们这篇文章来介绍activiti中的流程变量. 二.正文 流程变量与我们寻常理解的变量是一样的,仅仅只是是用在了我们act ...

  3. 工作流学习——Activiti流程实例、任务管理四步曲 (zhuan)

    http://blog.csdn.net/zwk626542417/article/details/46646565 ***************************************** ...

  4. 工作流学习——重要概念扫盲篇一步曲 (zhuan)

    http://blog.csdn.net/zwk626542417/article/details/46592471 ***************************************** ...

  5. 工作流学习——Activiti流程定义管理三步曲 (zhuan)

    http://blog.csdn.net/zwk626542417/article/details/46602419 ***************************************** ...

  6. Activiti流程变量五步曲 ——by fightingKing

    http://blog.csdn.net/zwk626542417/article/details/46648139 一.前言 上一篇文章我们将流程实例的启动与查询,任务的办理查询都进行了介绍,我们这 ...

  7. Activiti工作流学习笔记(三)——自动生成28张数据库表的底层原理分析

    原创/朱季谦 我接触工作流引擎Activiti已有两年之久,但一直都只限于熟悉其各类API的使用,对底层的实现,则存在较大的盲区. Activiti这个开源框架在设计上,其实存在不少值得学习和思考的地 ...

  8. Activiti工作流学习(一)部署对象和流程定义

    一.前言 前一段时间在工作中,使用了流程审批,对api的调用非常不熟悉,都是调用别人写好的接口在界面上进行显示,基本了解了流程审批的主要步骤,现对流程审批进行学习,主要是调用api进行CRUD操作,感 ...

  9. Activiti工作流学习之流程图应用详解

    Activiti工作流学习之流程图应用详解 1.目的  了解Activiti工作流是怎样应用流程图的. 2.环境准备2.1.相关软件及版本    jdk版本:Jdk1.7及以上 IDE:eclipse ...

随机推荐

  1. 排序练习——找出前m大的数字 分类: 排序 2015-06-08 09:33 21人阅读 评论(0) 收藏

    排序练习--找出前m大的数字 Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 给定n个数字,找出前m大的数字.   输入  多组输 ...

  2. CSUFT 1005 Coffin Tiles

    1005: Coffin Tiles Time Limit: 1 Sec      Memory Limit: 128 MB Submit: 2      Solved: 2 Description ...

  3. php四种基础算法:冒泡,选择,插入和快速排序法

    转自:http://www.php100.com/html/php/rumen/2013/1029/6333.html 许多人都说 算法是程序的核心,一个程序的好于差,关键是这个程序算法的优劣.作为一 ...

  4. hdu 1205 从整体考虑

    吃糖果 Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Submiss ...

  5. CentOS安装solr 4.10.3

    Solr是什么? Solr 是Apache下的一个顶级开源项目,采用Java开发,它是基于Lucene的全文搜索服务器.Solr提供了比Lucene更为丰富的查询语言,同时实现了可配置.可扩展,并对索 ...

  6. 微信支付:redirect-uri参数错误 的解决办法

    redirect_url参数错误: 报这个错误,说明你的公众号后台授权设置有问题(一般有两处) 一:检查授权目录 答:支付授权目录是网站发起请求的页面所在目录,并且必须是能通过url地址访问的(与真实 ...

  7. 怎样实现UIView的旋转

    首先创建界面,在viewDidLoad创建view以及button 相关代码如下 -(void)viewDidLoad { [super viewDidLoad]; viewDemo = [[UIVi ...

  8. centos系统下设置固定IP+dns

    笔者用的linux系统是centos版本的,在次之前linux是空白,今天我在物理机用XSHELL连接虚拟机中的centos时候出现连接失败的情况,我的第一反应就是IP是不是变了?打开虚拟机之后在终端 ...

  9. 【leetcode❤python】 36. Valid Sudoku

    #-*- coding: UTF-8 -*-#特定的九个格内1-9的个数至多为1#依次检查每行,每列,每个子九宫格是否出现重复元素,如果出现返回false,否则返回true.class Solutio ...

  10. IOS设计模式之一(MVC模式,单例模式)

    iOS 设计模式-你可能已经听说过这个词,但是你真正理解它意味着什么吗?虽然大多数的开发者可能都会认为设计模式是非常重要的,然而关于设计模式这一主题的文章却不多,并且有时候我们开发者在写代码的时候也不 ...