1. 程式人生 > >Activiti工作流框架學習(二)——使用Activiti提供的API完成流程操作

Activiti工作流框架學習(二)——使用Activiti提供的API完成流程操作

可以在專案中加入log4j,將logj4.properties檔案拷入到src目錄下,這樣框架執行的sql就可以輸出到到控制檯,log4j提供的日誌級別有以下幾種:

Fatal  error  warn  info  debug  trace

一、部署流程定義

1,在工程專案下建立原始碼資料夾process

2,在該檔案下下面新建立一個工作流流程定義檔案test1.bpmn(NewàActivit Diagram)

3,在test1.bpmn檔案定義請假流程或者是報銷流程

4,測試程式碼

public class ActivitiAPI {
   //首先獲得預設的流程引擎,在建立時會自動載入classpath下得activiti.cfg.xml或者是activiti-context.xml
   ProcessEngine processEngine= ProcessEngines.getDefaultProcessEngine();
   /**
     * 1.部署流程定義
     * 會在三張表中產生資料:
      * act_ge_bytearray 產生兩條資料
     *act_re_deployment 產生一條資料
     *act_re_procdef 產生一條資料
    * 方式一:讀取單個的流程定義檔案
    * 方式二:讀取zip壓縮檔案
    */
   @Test
   public void deploy() {
      // 獲取倉庫服務並建立釋出配置物件
      DeploymentBuilder deploymentBuilder = processEngine
            .getRepositoryService().createDeployment();
      // 方式一:設定釋出資訊
      deploymentBuilder.name("請假流程部署");//新增部署規則的名稱
// 讀取單個的流程定義檔案
      deploymentBuilder.addClasspathResource("test1.bpmn");
// 新增規則圖片  不新增會自動產生一個圖片不推薦
      deploymentBuilder.addClasspathResource("test1.png");
      Deployment
      deployment =deploymentBuilder.deploy();
 
      // 方式二:讀取zip壓縮檔案
      /*ZipInputStream zipInputStream = new ZipInputStream(this.getClass()
   .getClassLoader().getResourceAsStream("process.zip"));
      deploymentBuilder.addZipInputStream(zipInputStream);
      Deployment deployment =deploymentBuilder.deploy();*/
   }
   }

部署流程定義步驟:

  1)     首先獲得預設的流程引擎getDefaultProcessEngine(),在建立時會自動載入classpath下得activiti-context.xml或者是activiti.cfg.xml

  2)     通過流程引擎獲取了一個RepositoryService物件也就是倉庫服務物件

  3)     由倉庫的服務物件建立一個部署物件配置物件,用來封裝部署環境的相關配置。

  4)     這是一個鏈式程式設計,在部署配置物件中設定顯示名,上傳規則檔案相對classpath的地址。

  5)     部署,也是往資料庫中儲存流程定義的過程。

  6)     這一步在資料庫中將操作三張表:

    a)     act_re_deployment

       存放流程定義的顯示名和部署時間,每部署一次增加一條記錄

    b)     act_re_procdef

       存放流程定義的屬性資訊,部署每個新的流程定義都會在這張表中增加一條記錄。

    c)     act_ge_bytearray

       儲存流程定義相關的部署資訊。即流程定義文件的存放地。每部署一次就會增加兩條記錄,一條是關於bpmn規則檔案的,一條是圖片的(如果部署時只指定了bpmn一個檔案,activiti會在部署時解析bpmn檔案內容自動生成流程圖)。兩個檔案不是很大,都是以二進位制形式儲存在資料庫中。

二、查詢流程定義

/**
    * 查詢流程定義列表
    */
   
@Test
   public void queryProcessDefinition(){
      // 流程定義查詢物件,用於查詢表act_re_procdef,新增條件查詢
      ProcessDefinitionQuery query = processEngine.getRepositoryService()
            .createProcessDefinitionQuery();
      // 新增過濾條件
      query.processDefinitionKey("bxlc");
      // 新增排序條件降序排序
      query.orderByProcessDefinitionVersion().desc();
      // 新增分頁查詢
      query.listPage(0, 10);
      List<ProcessDefinition> list =query.list();
      for(ProcessDefinition pd : list) {
System.out.println(pd.getName()+ "" + pd.getId());
      }
   }

流程定義查詢步驟:

 1)     因為流程定義的資訊存放在倉庫中,所以應該獲取RepositoryService。

  2)     建立流程定義查詢物件,可以在ProcessDefinitionQuery上設定查詢過濾引數

  3)     呼叫ProcessDefinitionQuery物件的list方法,執行查詢,獲得符合條件的流程定義列表

  4)     由執行結果可以看出:

    a)     Key和Name的值為:bpmn檔案process節點的id和name的屬性值

    b)     key屬性被用來區別不同的流程定義。

    c)     帶有特定key的流程定義第一次部署時,version為1。之後每次部署都會在當前最高版本號上加1

 d)     Id的值的生成規則為:{processDefinitionKey}:{processDefinitionVersion}:{generated-id},這裡的generated-id是一個自動生成的唯一的數字

    e)     重複部署一次,deploymentId的值以一定的形式變化

三、刪除流程定義

/**
    * 刪除流程定義(通過刪除部署資訊達到刪除流程定義的目的)
*刪除act_re_procdef和act_re_deployment表中的一條記錄
    */
@Test
public void delDeployment() throwsException {
 // 獲取倉庫服務物件
 RepositoryService repositoryService =processEngine.getRepositoryService();
 // 刪除釋出資訊
 String deploymentId = "1";
 // 普通刪除,如果當前規則下有正在執行的流程,則拋異常
 repositoryService.deleteDeployment(deploymentId);
 // 級聯刪除,會刪除和當前規則相關的所有資訊,包括歷史
 repositoryService.deleteDeployment(deploymentId, true);
 }
四、啟動流程例項

什麼是流程例項?根據一個流程定義具體的一次執行過程就是一個流程例項,一個流程定義對應多個流程例項(一對多關係),比如:已經定義了一個請假流程,張三同學走了一次該流程這就是啟動一次流程例項

/**根據流程定義的id啟動一個流程例項,這個流程定義的Id來自act_re_procdef
    * 啟動一次流程例項act_ru_execution表增加一條資料
    */
   @Test
   public void startProcessInstance() {
//獲取流程定義ID
      /*
       *String processDefinitionId = "qjlc:9:1204"; ProcessInstance
       *processInstance =
       *processEngine.getRuntimeService().startProcessInstanceById
       * (processDefinitionId );System.out.println(processInstance.getId());
       */
//自動選擇最新版本的流程定義啟動流程例項建議使用key來啟動
      String processDefinitionKey = "qjlc";
      ProcessInstance processInstance = processEngine.getRuntimeService()
            .startProcessInstanceByKey(processDefinitionKey);
      System.out.println(processInstance.getId());
   }
五、查詢流程例項列表
/**
    * 查詢流程例項列表,查詢act_ru_execution表
    */
   @Test
   public void queryProcessInstance(){
      //流程例項查詢物件,查詢act_ru_execution表
      ProcessInstanceQuery query = processEngine.getRuntimeService().createProcessInstanceQuery();
      query.processDefinitionKey("qjlc");
      query.orderByProcessInstanceId().desc();
      query.listPage(0, 2);
      List<ProcessInstance> list =query.list();
      for(ProcessInstance pi : list) {
         System.out.println(pi.getId()+ " " + pi.getActivityId());
      }
   }
六、結束流程例項
/**
    * 結束流程例項,操作的表
    * 執行表:act_ru_execution(刪除一條資料)
    * 任務表 act_ru_task(刪除一條資料)
    */
   @Test
   public void deleteProcessInstance(){
      String processInstanceId = "1601";
      processEngine.getRuntimeService().deleteProcessInstance(processInstanceId, "我願意");
   }
七、查詢部署資訊
/**
    * 查詢部署列表(同一個流程定義因為修改會進行多次的部署,版本號不一樣version會增加,每次部署act_re_deployment表增加一條記錄)
    */
   @Test
   public void queryDeployment() {
      // 部署查詢物件,查詢表act_re_deployment
      DeploymentQuery query = processEngine.getRepositoryService()
            .createDeploymentQuery();
      List<Deployment> list =query.list();
      for (Deploymentdeployment : list) {
         String id = deployment.getId();
         System.out.println(id);
      }
   }
八、刪除部署資訊
/**
    * 刪除部署資訊,刪除act_re_procdef和act_re_deployment表中的一條記錄
    */
   @Test
   public void deleteDeployment() {
      String deploymentId = "101";
      // processEngine.getRepositoryService().deleteDeployment(deploymentId);
      //true代表刪除級聯關聯表資訊
      processEngine.getRepositoryService().deleteDeployment(deploymentId,
            true);
   }
九、查詢一次流程部署對應的檔名稱(bpmn,png)和輸入流
/**
    * 查詢一次部署對應的流程定義檔名稱和對應的輸入流(bpmn,png)
    * @throws Exception
    */
   @Test
   public void queryProcessFile() throws Exception {
      String deploymentId = "101";
      List<String> names = processEngine.getRepositoryService()
            .getDeploymentResourceNames(deploymentId);
      for (String name :names) {
         System.out.println(name);
         InputStream in = processEngine.getRepositoryService()
                .getResourceAsStream(deploymentId,name);
         // 將檔案儲存到本地磁碟
         /*
          * OutputStream out = new FileOutputStream(newFile("d:\\" + name));
          * byte[] b = new byte[1024]; int len= 0; while((len =
          * in.read(b))!=-1) { out.write(b, 0, len);} out.close();
          */
//使用org.apache.commons.io.FileUtils的工具類
         FileUtils.copyInputStreamToFile(in,new File("d:\\" + name));
         in.close();
      }
   }
十、獲取流程定義圖示(png檔案)
/**
    * 獲得png檔案的輸入流
    *
    * @throws Exception
    */
   @Test
   public void getPng() throws Exception {
      String processDefinitionId = "qjlc:9:1204";
      InputStream pngInputStream = processEngine.getRepositoryService()
            .getProcessDiagram(processDefinitionId);
      FileUtils.copyInputStreamToFile(pngInputStream,new File("d:\\my.png"));
   }
十一、      查詢個人任務列表
/**
    * 查詢任務列表查詢act_ru_task表
 
    */
   @Test
   public void queryTask() {
TaskQuery query= processEngine.getTaskService().createTaskQuery();
      String assignee = "張三";
      query.taskAssignee(assignee);
query.orderByTaskCreateTime().desc();
      List<Task> list = query.list();
      for (Task task :list) {
         System.out.println(task.getId()+ " " + task.getName());
      }
   }
十二、      辦理任務
/**
    * 辦理任務
    */
   @Test
   public void completeTask(){
      String taskId= "404";
      processEngine.getTaskService().complete(taskId);
   }
十三、      直接將流程想下執行一步管理員使用者擁有該許可權
/**
    * 直接將流程向下執行一步act_ru_task表增加一條資料,直接跳過一步
    */
   @Test
   public void signal(){
      String executionId = "2701";//流程例項id
      processEngine.getRuntimeService().signal(executionId);
   }