一.Activiti 的概念
工作流(Workflow),指“業務過程的部分或整體在計算機應用環境下的自動化”。是對工作流程及其各操作步驟之間業務規則的抽象、概括描述。在計算機中,工作流屬於計算機支持的協同工作(CSCW)的一部分。後者是普遍地研究一個羣體如何在計算機的幫助下實現協同工作的。工作流主要解決的主要問題是:爲了實現某個業務目標,利用計算機在多個參與者之間按某種預定規則自動傳遞文檔、信息或者任務。
二 工作流的發展流程
bpm:business process managerment 商業流程管理
jbpm:jboss business process managerment
pdl:process definition language 流程定義語言
jpdl:jboss process definition language
bpmn:Business Process Model and Notation,BPMN 流程定義語言中的每一個元素的規定
三.工作流的特點
1、流程圖遵循bpmn規範,這是一個國際規範
2、activiti5對流程的控制是基於表
3、activiti5對數據庫的操作採用的是mybaties技術
4、activiti5提供了一套完整的api操作表,而不需要使用mybaties技術
5、activiti5是能與spring進行整合的
1)、jbpm3.0
2)、jbpm4.0以上的版本
3)、activiti5 jbpm原先的團隊開發的 與jbpm4非常相似
4)、jbpm5.0 jboss公司的jbpm
四.工作流的操作流程
開發準備好activiti工作流的環境(下載框架,配置到eclipse中的插件中去,下載相關的jar包 生成數據表)
- 畫流程圖
2、把流程圖部署到activiti5的工作流的引擎中(啓動流程實例)
3、填寫請假單
4、提交申請
5、部門經理進行審批
6、總經理審
上述的流程控制的特點:
1)、如果沒有進行請假申請,那麼審批人是不知道這個任務的
2)、如果部門經理沒有審批該任務,總經理不知道該任務的存在
3)、登錄人登錄系統以後,只能看到各自的任務
五.工作流中的基本介紹
5.1 工作流的引擎
processEngin對象是工作流的核心,負責生成流程運行時的各種實例和數據,監控和管理流程的運行
5.2 BPMN
業務流程的建模和標註,描述流程的基本符號,包括一個圖元如何組成一個業務流程圖。
六 工作流的第一個demo
Mysql 數據庫 jdk1.6 eclipse activity的相關jar包
安裝流程設計器(eclipse的插件)
第一種方式:安裝流程:help--》install new soft -->填入字段(ActivityBPMN,Localtion:http://activiti.org/designer/update/)-->>點擊複選框
第二種方式: activiti包--》放入eclipse-drop-plugus,zip到drop文件夾中--》重啓eclipsre new other 打開面板
導入相關的jar包(項目我會上傳到github上)
測試環境是否已經安裝好了
File -->new -->activiti5 的界面
初始化數據庫(沒有用配置的操作)
添加並制定配置文件 (這種方式比較多)
Activity-test/web-inf/class 下有個activiti-content.xml 把數據庫的配置寫入(和spring配置文件差不多),後改爲Activit.cfg.xml 用於流程引擎的相關配置
初始化數據庫(沒有用配置的操作)
添加並制定配置文件 (這種方式比較多)
Activity-test/web-inf/class 下有個activiti-content.xml 把數據庫的配置寫入(和spring配置文件差不多),後改爲Activit.cfg.xml 用於流程引擎的相關配置
打開菜單window-->preferences-->Activiti-->save
Create process definition image when saving the diagram 選中
雖然流程引擎在單獨部署bpmn文件時會自動生成圖片,但在實際開發過程中,自動生成的圖片會導致和BPMN中的座標有出入,在實際項目中展示流程當前位置圖會有問題。
所以完成配置以後,會由我們自己來管理流程圖片。在發佈流程時把流程規則文件和流程圖片一起上傳就行了。
畫bpmn流程圖
將流程圖部署到引擎中(部署的三種方式)
classpath
inputstream
zipinputstream
啓動流程實例
完成各個節點的任務
七. 相關的API操i作以及涉及到的表操作
流程圖的部署操作:
* 1、部署
* classpath
* inputstream
* zipinputstream
* 2、查詢
* 查詢流程部署
* 查詢所有的流程部署
* 根據deploymentID查詢流程部署
* 查詢流程定義
* 查詢所有的流程定義
* 根據pdid查詢流程定義
* 根據pdkey查詢流程定義
* 根據 deploymentID查詢流程定義
* 3、刪除
* 4、查看流程圖
* 可以根據pdid查詢流程圖
* 可以根據deploymentID,resourceName查詢流程圖
*/
* 1、涉及到的表
* act_re_deployment 部署表
* 1、說明
* 描述的是一次動作,每部署一次,在該表中增加一行記錄
* 2、字段
* ID_: 部署ID
* act_re_procdef 流程定義表
* 1、說明
* 是用來描述流程定義的
* 如果key值或者name值發生變化,相當於一個全新的流程定義,這個時候再次部署,版本號從1開始計算
* 2、字段
* name_:流程定義名稱
* key_:流程定義key
* version_:版本
* deployment_id_:部署ID
* pdid:流程定義ID {processKey}:{processVersion}:隨機數
* act_ge_bytearry 通用數據表 該表存放了hellworld.bpmn和helloworld.png數據
* 1、說明
* 在部署的時候,部署的bpmn和png都存放在該表中
* 2、字段
* deploymentID:部署ID 將來可以根據部署ID查詢圖片
//測試的相關流程
package cn.xgs.a_helloword_test;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.junit.Test;
/*
* 1、畫流程圖
* 2、把該流程部署到activiti5的引擎中
* 3、啓動流程實例
* 4、請假
* 5、部門經理審批
* 6、總經理審批
*/
public class HellowordTest {
//部署程序
@Test
public void testDeploy() {
//獲得流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
processEngine.getRepositoryService().createDeployment().addClasspathResource("cn/xgs/a_helloword_test/helloworld.bpmn")
.addClasspathResource("cn/xgs/a_helloword_test/helloworld.png").deploy();
}
//啓動流程實例
@Test
public void testStartProcessInstance() {
//pdkey 是流程定義的名稱
String pdkey = "itheima09";
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
processEngine.getRuntimeService().startProcessInstanceByKey(pdkey);
}
//完成請假申報任務
@Test
public void testFinishTask_Applicator() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
processEngine.getTaskService().complete("104");
}
/**
* 完成部門經理審批的任務
*/
@Test
public void testFinshTask_ManagerApprove(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
processEngine.getTaskService()
.complete("101");
}
/**
* 完成總經理審批的任務
*/
@Test
public void testFinshTask_BossApprove(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
processEngine.getTaskService()
.complete("202");
}
}
將流程圖部署,並生成工作流的引擎
package cn.xgs.a_helloword_test.pd;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.zip.ZipInputStream;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.junit.Test;
public class PDManager {
@Test
public void testDeploy_Classpath(){
//得到一個流程引擎 classPath 進行部署
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
Deployment deployment = processEngine.getRepositoryService()
.createDeployment().addClasspathResource("cn/xgs/a_helloword_test/helloworld.bpmn")
.addClasspathResource("cn/xgs/a_helloword_test/helloworld.png")
.deploy();
System.out.println(deployment.getId());
System.out.println(deployment.getName());
}
/**
* 根據inputStream進行部署
*/
@Test
public void testDeploy_Inputstream(){
InputStream inputStream = this.getClass().
getClassLoader().
getResourceAsStream("cn/xgs/a_helloword_test/helloworld.bpmn");
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
processEngine.getRepositoryService()
.createDeployment()
.addInputStream("cn/xgs/a_helloword_test/helloworld.bpmn", inputStream)
.deploy();
}
/**
* 根據zipinputstream進行部署
*/
@Test
public void testDeploy_ZipinputStream(){
InputStream inputStream = this.getClass().
getClassLoader().
getResourceAsStream("cn/xgs/a_helloword_test/helloworld.zip");
ZipInputStream zipInputStream = new ZipInputStream(inputStream);
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
processEngine.getRepositoryService()
.createDeployment()
.addZipInputStream(zipInputStream)
.deploy();
}
//查詢所有的流程部署
@Test
public void testQueryDeployment() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
List<Deployment> dList = processEngine.getRepositoryService().createDeploymentQuery().list();//創建一個部署查詢
for(Deployment deployment:dList) {
System.out.println(deployment.getId());
}
}
//根據部署的id進行查詢
@Test
public void testQueryDeploymentByID() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
Deployment deployment = processEngine.getRepositoryService().createDeploymentQuery().deploymentId("401").singleResult();
System.out.println(deployment.getId());
}
//查詢流程定義
@Test
public void testQueryPD() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
List<ProcessDefinition> pds = processEngine.getRepositoryService().createProcessDefinitionQuery().list();
for(ProcessDefinition pd:pds) {
System.out.println("pdid"+pd.getId());
System.out.println("version"+pd.getVersion());
System.out.println("key"+pd.getKey());
}
}
//根據pid查詢
@Test
public void testQueryPDByPDID(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
ProcessDefinition pd = processEngine.getRepositoryService().createProcessDefinitionQuery()
.processDefinitionId("itheima09:3:504").singleResult();
System.out.println(pd.getKey());
}
//根據pdkey查詢
@Test
public void testQueryPDByPDKEY(){
//創建引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
List<ProcessDefinition> pdList= processEngine.getRepositoryService().createProcessDefinitionQuery()
.processDefinitionKeyLike("itheima09").list();
for(ProcessDefinition pd:pdList){
System.out.print("key:"+pd.getKey()+",");
System.out.print("version:"+pd.getVersion()+",");
System.out.println("pdid:"+pd.getId());
}
}
//刪除 根據deploymentID進行刪除
@Test
public void testDelete() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//processEngine.getRepositoryService()
//.deleteDeployment("1");//用該API只能刪除流程定義的內容和部署的內容
processEngine.getRepositoryService()
.deleteDeployment("1", true);//刪除了關於deploymentID爲1的所有的數據,包括:流程定義、流程部署、任務等信息
}
/**
* 查詢流程圖
*/
@Test
public void showImage() throws Exception{
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
InputStream inputStream = processEngine.getRepositoryService()
.getProcessDiagram("itheima09:3:504");
OutputStream outputStream = new FileOutputStream("e:/processimg1.png");
for(int b=-1;(b=inputStream.read())!=-1;){
outputStream.write(b);
}
inputStream.close();
outputStream.close();
InputStream inputStream2 = processEngine.getRepositoryService()
.getResourceAsStream("401", "cn/xgs/a_helloword_test/helloworld.png");
OutputStream outputStream2 = new FileOutputStream("e:/processimg2.png");
for(int b=-1;(b=inputStream2.read())!=-1;){
outputStream2.write(b);
}
inputStream2.close();
outputStream2.close();
}
}
//流程的定義
package cn.xgs.a_helloword_test.pi;
import java.util.List;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.Test;
public class PITest {
@Test
public void testDeploy(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
processEngine.getRepositoryService()
.createDeployment()
.addClasspathResource("cn/xgs/a_helloword_test/pi/qingjia.bpmn")
.deploy();
}
//啓動實例
@Test
public void testStartPI() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//.startProcessInstanceByKey(processDefinitionKey) 根據pdkey啓動流程實例 默認根據最高版本的啓動
ProcessInstance pi = processEngine.getRuntimeService().startProcessInstanceById("qingjia:1:1004");
System.out.println(pi.getId());
System.err.println(pi.getProcessInstanceId());
System.err.println(pi.getProcessDefinitionId());
}
/**
* 查詢正在執行的任務
*/
@Test
public void testQueryTask() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
List<org.activiti.engine.task.Task> taList = processEngine.getTaskService().createTaskQuery().list();
for(org.activiti.engine.task.Task task:taList ) {
System.out.println("taskID"+task.getId());
System.out.println("taskID"+task.getName());
}
}
/**
* 可以根據任務的執行人查詢當前正在執行的任務
*/
@Test
public void TestQueryTaskByAssignee() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
List<Task> taskList = processEngine.getTaskService().createTaskQuery().taskAssignee("張三").list();
for(Task task:taskList) {
System.out.print("taskid:"+task.getId()+",");
System.out.println("taskname:"+task.getName());
}
}
/**
* 完成任務 過流程
*/
@Test
public void testFinishTask(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
processEngine.getTaskService()
.complete("1004");
}
/**
* 判斷當前的流程實例已經結束
* 根據piid查詢流程實例,如果查詢出來的結果爲null,流程實例已經結束了
* 如果不爲null,流程實例沒有結束
*/
@Test
public void testIsEndPI(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
ProcessInstance pi = processEngine.getRuntimeService()
.createProcessInstanceQuery()
.processInstanceId("1101")
.singleResult();
System.out.println(pi);
}
}