宅急送 项目第八天 JBPM工作流框架

本文档介绍了工作流框架的重要性和JBPM的基本概念。通过一个演示程序,展示了如何定制和发布业务流程,并通过管理员、员工、部门经理和总经理的角色进行操作。详细探讨了JBPM的安装、流程设计、开发环境搭建、流程定义管理和实例管理,以及任务和流程变量的管理。文章还提到了权限管理模块和JBPM在项目中的应用。
摘要由CSDN通过智能技术生成

项目第八天和项目第九天 学习 JBPM 理论部分
项目第十天 权限管理模块
项目第十一天 项目第十二天 JBPM 应用

1. 工作流框架概述

1.1. 什么是工作流

工作流(Workflow),就是“业务过程的部分或整体在计算机应用环境下的自动化”
工作流技术 是 OA 系统中最关键的一环 !!!
简单的说,就是将工作的流程通过程序管理起来,以表单审核和任务办理为主体,实现办公自动化

工作流开发: 实现业务流程可定制化,将定制业务流程保存到工作流框架系统中,用户登录之后,询问工作流,哪个流程该我完成了,工作流返回需要用户办理任务节点, 用户选择对应任务进行办理,在办理任务后,流程会自动流行下一个节点 !

1.2. 通过工作流实例来了解工作流框架

通过 “演示程序” 了解工作流

1、 定制业务流程
MyProcessDesigner_流程设计器

这里写图片描述

完成流程图

这里写图片描述

点击保存按钮 , 生成holiday.zip 压缩包

    ---- process.jpdl.xml 流程描述文件
    ---- process.png 流程图片 
2、 将业务流程发布 工作流系统中

使用 tomcat-6.0.14 运行 (配置 JAVA_HOME),自带 MyJbpm4-Console 工作流Demo
注意: 在运行项目之前,先配置项目 hibernate 配置文件

修改 jbpm.hibernate.cfg.xml

启动tomcat ,访问 http://localhost:8080/MyJbpm4-Console/

3、 使用 admin账户登陆 (无密码)

发布 holiday.zip
启动流程,流程停留到 员工请假申请 节点

4、 使用 员工 登陆

查看个人任务

这里写图片描述

这里写图片描述

5、 使用部门经理登陆

查看个人任务

这里写图片描述

6、 使用总经理登陆

查看个人任务

所有流程 基本办理模式都是相似的, 先登陆系统, 查询我的个人任务, 办理个人任务, 流程流转 !!

2. JBPM学习

2.1. 什么是JBPM ?

JBPM,全称是Java Business Process Management(业务流程管理)
是一款开源工作流框架

企业主流工作流产品: JBPM、OSWorkFlow、 OFBIZ、
OFBIZ 很多大公司在用 ,构建大中型企业级、跨平台、跨数据库、跨应用服务器的多层、分布式电子商务类WEB应用系统的框架。

企业主流JBPM版本, 3.x 、4.x

JBPM 从5.x 开始分流 ,原来JBPM开发团队,离开JBOSS公司 ,原开发团队写工作流框架叫做Activity (是对JBPM 延续 ,数据库技术使用 MyBatis )、JBOSS公司另外一个团队推出 JBPM5 (和 JBPM4没有任务关系 )

2.2. 下载JBPM开发包

http://sourceforge.net/projects/jbpm/files/
下载JBPM4.4

这里写图片描述

2.3. 安装JBPM流程设计器

安装Eclipse 的JBPM 流程设计器插件
—- 对eclipse内置插件有要求 ,有些myeclipse内部缺少需要插件

步骤一: 进行myeclipse 配置中心

这里写图片描述

步骤二: 进入SoftWare 管理界面
点击 Add site

这里写图片描述

这里写图片描述

找到 jbpm解压目录/install/src/gpd/ 插件的zip包

展开jbpm插件选项,将每一项右键添加 profile

这里写图片描述

最后点击下方 apply 8 changes 进行安装 ,安装后会重启MyEclipse

在新建中 出现

这里写图片描述

说明安装插件成功 !!!

2.4. 使用 JPDL流程设计器,设计流程

习惯性,在开发中设计流程图,新建 source forlder (jpdl/xml)
使用插件自带设计器 编写JBPM 流程

通过 properties 视图,修改图中节点属性

这里写图片描述

<process name="holiday" xmlns="http://jbpm.org/4.4/jpdl">
   <start name="start1" g="211,21,48,48">
      <transition name="to 员工请假申请" to="员工请假申请" g="-95,-17"/>
   </start>
   <end name="end1" g="206,288,48,48"/>
   <task name="员工请假申请" g="188,105,92,52">
      <transition name="to 部门经理审批" to="部门经理审批" g="-95,-17"/>
   </task>
   <task name="部门经理审批" g="192,192,92,52">
      <transition name="to end1" to="end1" g="-47,-17"/>
   </task>
</process>

需要为 流程设计器,设置schema 提示 , 选择jbpm解压目录/src/jpdl-4.4.xsd

这里写图片描述

2.5. 搭建JBPM开发环境

2.5.1. 在项目中导入JBPM的jar包

{JBPM_HOME}/jbpm.jar 开发jbpm核心jar 包
去掉 servlet-api、 junit、 slf4j-*
替换 slf4j 1.5.8的jar包

2.5.2. 配置文件导入

src/log4j.properties
将 JBPM_HOME/examples/src/ 下面文件复制到 src目录

jbpm.cfg.xml (JBPM框架核心配置文件)
jbpm.hibernate.cfg.xml (hibernate 配置文件、修改数据库连接参数)

修改 hibernate 连接参数时 ,改为mysql参数

<property name="hibernate.dialect">
org.hibernate.dialect.MySQL5InnoDBDialect 
</property>
<property name="hibernate.connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="hibernate.connection.url">
jdbc:mysql:///jbpm01
</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">abc</property>
<property name="hibernate.hbm2ddl.auto">update</property>

注意: 方言必须要用 org.hibernate.dialect.MySQL5InnoDBDialect,否则在流程结束时会报一个异常!

2.5.3. 编写程序,初始化JBPM数据表
// 1、 定义配置类,用来加载jbpm配置文件
Configuration configuration = new Configuration();
// 2、加载配置文件,初始化jbpm环境
configuration.buildProcessEngine();

创建18张数据表
参加 : 资料/ JBPM4.4数据表结构说明.rtf 文档

这里写图片描述

3. JBPM工作流操作— 流程定义管理

目的: 将设计好业务流程,部署到JBPM工作流引擎中!

3.1. 设计流程图

JBPM流程设计,分为线上设计器 和 线下设计器两种
很多企业开发中,公司都会定制自己的线上设计器 ,打开一个网页,在网页上直接设计JBPM业务流程,通过保存按钮,直接将设计好流程部署系统中!

MyEclipse 安装GPD插件,属于线下设计器 ,需要将设计好流程通过文件上传的方式,发布到JBPM系统中

这里写图片描述

生成 jpdl/xml文件(流程描述文件)、 png流程图 两个文件

3.2. 将设计好流程部署到JBPM系统中

JBPM程序开发步骤:
步骤一: 获得流程引擎对象 ProcessEngine

// 步骤一: 获得流程引擎
ProcessEngine processEngine = 
new Configuration().buildProcessEngine();

步骤二: 获得对应Service对象

这里写图片描述

JBPM内部提供六个Service,用来完成不同操作

RepositoryService 用来进行流程定义操作 
ExecutionService 用来进行流程实例操作 
TaskService  用来进行任务操作
IdentityService 用来进行JBPM用户操作
HistoryService 用来对流程历史记录进行操作 
ManagementService 用来进行定时任务调度 (管理job)
// 步骤二: 获得对应Service
RepositoryService repositoryService =
processEngine.getRepositoryService();

步骤三: 进行操作 、发布流程

这里写图片描述

常用: addResourceFromZipInputStream 、 addResourceFromClasspath

// 步骤三: 进行业务操作
NewDeployment deployment = repositoryService.createDeployment(); // 获得发布对象
deployment.addResourceFromClasspath("holiday.jpdl.xml");
deployment.addResourceFromClasspath("holiday.png");
deployment.deploy(); // 执行发布的动作

3.3. 详细分析流程定义发布过程中数据表变化

jbpm4_property 全局属性表
在初始化18张表时候,向表中已经插入一条记录

这里写图片描述

这个表中主要存在下次操作的起始记录id ,JBPM框架采用流水ID方式
下次数据库操作,id 从1 开始

jbpm4_deployment 流程定义发布表 ,每次发布一个新流程,在表中保存一条记录

这里写图片描述

jbpm4_lob 二进制数据表,在发布流程时,会发布一些文件,一个文件,对应lob中一条记录

这里写图片描述

jbpm4_deployprop 流程定义属性表,用来存放每次发布流程定义的属性信息,一个流程定义,对应四条属性信息

这里写图片描述

Key字段保存属性名称
landid: 使用JBPM的jpdl语言 的版本
pdId: 流程定义编号(唯一标识), 由 pdKey-pdVersion 组成
pdkey : 流程关键字
pdversion : 流程版本号

注意: 每次数据库操作后, jbpm4_property表 next.dbid 要更新,+10000

案例: 发布zip压缩包

NewDeployment deployment = repositoryService.createDeployment(); // 获得发布对象
deployment.addResourcesFromZipInputStream(new ZipInputStream(new FileInputStream("holiday.zip")));
deployment.deploy();

3.4. 流程定义查看

通过 ProcessDefinitionQuery查询流程定义信息
查看所有流程定义

ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
        List<ProcessDefinition> list = processDefinitionQuery.list();
        System.out.println(list.size());
        for (ProcessDefinition processDefinition : list) {
            System.out.println("ID:" + processDefinition.getId());
            System.out.println("名称:" + processDefinition.getName());
            System.out.println("Key:" + processDefinition.getKey());
            System.out.println("版本:" + 
            processDefinition.getVersion());
}

参考 holiday.jpdl.xml

<process name="holiday" xmlns="http://jbpm.org/4.4/jpdl">

name: holiday 对应流程定义名称
key 没有指定,将默认使用 name的值
version : 发布相同key的流程时,version版本每次+1
id : 就是流程定义编号 ,对应数据表 pdId 由 key-version 组成

这里写图片描述

为流程定义查询指定条件

3.5. 查看流程图

使用 RepositoryService 提供

getResourceAsStream(deploymentId, resourceName)  方法 

这个方法 需要 发布编号 (jbpm4_deployment 的主键) 和 资源名称 (jbpm4_lob 表)

// 先根据 流程定编号 pdId ,查询流程发布编号 deploymentId
    ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
    processDefinitionQuery.processDefinitionId("holiday-2");
    ProcessDefinition processDefinition = processDefinitionQuery.uniqueResult();
    String deploymentId = processDefinition.getDeploymentId(); // 发布id

    // 获得资源名称
    String resourceName = processDefinition.getImageResourceName(); // 资源name

    // 获得图片资源流
    InputStream in = repositoryService.getResourceAsStream(deploymentId, resourceName);
    OutputStream out = new FileOutputStream("c:/holiday.png");
    int b;
    while ((b = in.read()) != -1) {
        out.write(b);
    }
    in.close();
    out.close();

3.6. 流程定义的删除

在实际已经应用的流程,不建议用户去删除 ,JBPM 在发布相同key的新流程时,version 递增 ! 没有必要将旧版本流程删除,影响到之前系统数据 。

这里写图片描述

通常使用 方式二 ,进行删除

删除 流程定义信息 jbpm4_deployment、jbpm4_lob、jbpm4_deployprop
删除 流程实例信息

4. JBPM工作流操作— 流程实例管理

问题: 流程定义和流程实例 是什么关系 ?
类似 类和对象的关系, 流程定义用来描述一个业务流程,完整节点和流转信息 (请假流程) ,流程实例是使用业务流程,进行一个具体业务数据操作 (张三请假)
* 一个流程定义 对应 很多个流程实例

4.1. 启动流程实例

对流程定义,启动一个具体的实例
对流程实例操作,使用 ExecutionService

启动流程实例可以根据 流程定义编号启动 或者 根据流程定义关键字启动

这里写图片描述

// 根据 pdid启动 (jbpm4_deployprop 流程定义属性表 )
executionService.startProcessInstanceById("holiday-1");

// 根据 pdKey启动 (jbpm4_deployprop 存在 key属性)
executionService.startProcessInstanceByKey(“holiday”); // key可以相同的
默认启动相同key 最高版本的流程!!

4.2. 详细分析启动流程实例影响的数据表

jbpm4_execution 正在运行流程实例信息表

这里写图片描述

这里写图片描述

ACTIVITYNAME_ 当前活动节点名称
ID_ (流程实例id 或者 执行id ): holiday.30001

jbpm4_hist_procinst 流程实例运行历史记录表

这里写图片描述

jbpm4_task 正在运行任务信息 (当流程执行task节点,task表插入记录 )

这里写图片描述

这里DBID 就是 taskId 任务编号 30002
jbpm4_hist_task 存在任务运行历史记录

这里写图片描述

jbpm4_hist_actinst 活动历史记录表

这里写图片描述

问题: 任务和活动 是什么关系 ?
任务是活动的一种 (活动节点 不只包含 任务节点 !!!)
表中TYPE字段,用来表示活动的类型 ,这里task,说明该活动是 任务!!!

4.3. 流程实例流转

通过ExecutionService的signalExecutionById 可以使JBPM工作流程转向下一个节点, 根据流程实例id (jbpm4_execution 表 ID_ 字段)进行流程向后流转

这里写图片描述

根据 实例id 和 目标transition的name属性 进行流转

// 根据实例id ,向后流转
// to 部门经理审批 是transition的name属性
executionService.signalExecutionById

(“holiday.30001”, “to 部门经理审批”);

这里写图片描述

4.4. 流程实例流转特殊操作 — 直接中止流程

这里写图片描述

5. JBPM工作流操作— 任务操作

ExecutionService.signalExecutionById(流程实例id) —- 使流程向后一步,到达下一节点 !
在实际开发中, 上面这个方法,不会用于task节点流转 !
—- 任务 是需要指定的人办理完成的 ,不会自动向后流转
—- 任务节点需要指定人来办理任务,在任务办理后,自动向后流转

5.1. 通过assignee属性 指定任务节点负责人

这里写图片描述

<task g="188,105,92,52" name="员工请假申请" assignee="员工">
    <transition g="-95,-17" name="to 部门经理审批" to="部门经理审批"/>
 </task>
 <task g="192,192,92,52" name="部门经理审批" assignee="部门经理">
    <transition g="-47,-17" name="to end1" to="end1"/>
 </task>

重新发布流程

5.2. 启动流程实例

executionService.startProcessInstanceByKey("holiday"); 

在 jbpm4_task 表

这里写图片描述

ASSIGNEE 就是当前任务的负责人 !

5.3. 任务节点操作

任务操作,需要使用 TaskService 完成

操作一: 查询当前流程实例的任务

TaskQuery taskQuery = taskService.createTaskQuery();
List<Task> list = taskQuery.executionId("holiday.10001").list();
System.out.println(list.size());
for (Task task : list) {
    System.out.println("任务编号:" + task.getId());
    System.out.println("任务名称:" + task.getName());
}

操作二: 我的个人任务

// 查看个人任务
List<Task> list = taskService.findPersonalTasks("员工");
System.out.println(list.size());
for (Task task : list) {
    System.out.println("任务编号:" + task.getId());
    System.out.println("任务名称:" + task.getName());
}

操作三: 办理个人任务
TaskService提供completeTask(taskId)完成指定的任务

// 办理任务
// taskId 就是 jbpm4_task表 DBID 字段
taskService.completeTask("10002");

办理任务后,流程自动流向下一个节点 !

6. JBPM工作流 流程变量管理

在使用JBPM 管理业务流程后,很多业务流程数据,需要和JBPM流程进行关联
和流程实例进行关联后业务数据,也叫 流程变量!

6.1. 流程变量支持哪些类型

这里写图片描述

将JBPM 支持流程变量类型 分为两大种 :基本类型 和 自定义对象类型

自定义对象类型支持
Long类型主键的 PO对象
String类型主键的PO对象
实现Serializable 接口的可序列化的对象

6.2. 流程的读写操作

第一种: 在ExecutionService 的 startProcessInstanceById 或 startProcessInstanceByKey 启动流程实例时关联流程变量

这里写图片描述

// 关联流程变量
Map<String, Object> variables = new HashMap<String, Object>();
variables.put("company", "传智播客");
executionService.startProcessInstanceByKey("holiday", variables);

流程变量保存 jbpm4_variable 表中!

这里写图片描述

第二种 : ExecutionService 结合 executionId 对流程变量进行读写操作
四个ID :
deploymentId 发布id : jbpm4_deployment 的 DBID
pdId (processDefinitionId) 流程定义id : jbpm4_deployprop 的pdId
executionId (processInstanceId) 流程实例id : jbpm4_execution 的 ID_
taskId 任务id : jbpm4_task 的 DBID

这里写图片描述

读取操作:

String company = 
(String) executionService.getVariable("holiday.30001", "company");
    System.out.println(company);

写入操作:

executionService.setVariable("holiday.30001", "pnum", 100);

第三种: 使用TaskService 结合 taskId 对变量进行读写操作

这里写图片描述

读取操作

int pnum = (Integer) taskService.getVariable("30003", "pnum");
        System.out.println(pnum);

写入操作

Map<String, Object> variables = new HashMap<String, Object>();
variables.put("weather", "多云无雨");
taskService.setVariables("30003", variables);

6.3. 复杂流程变量 写入

案例一: Serializable 可序列化对象
如果格式非法:

org.hibernate.HibernateException: instance not of expected entity type: org.jbpm.pvm.internal.type.variable.UnpersistableVariable is not a: 
org.jbpm.pvm.internal.type.Variable

这里写图片描述

这里写图片描述

在 variables 表

这里写图片描述

CLASS:blob 二进制数据
CONVERTER:ser-bytes 序列化的字节
LOB : 70001 就是 jbpm4_lob 表主键
数据保存 lob 表中

这里写图片描述

案例二: long类型主键的PO对象

这里写图片描述

这里写图片描述

在variables 表 ,保存记录

这里写图片描述

这里写图片描述

CLASSNAME 存放完整类名
LONG_VALUE 存在主键值

引入PO对象,数据保存在业务表,在JBPM中只是引入 完整类名和主键

其它

课前资料

这里写图片描述

JBPM4.4入门

这里写图片描述

里面有JBPM的详细教程

课后内容

这里写图片描述

工作流框架应用

这里写图片描述

课程视频内容

这里写图片描述

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值