1. 程式人生 > >activiti完整教程

activiti完整教程

轉載自:https://www.cnblogs.com/ginb/p/7624820.html

 

瞭解工作流

1、工作流(Workflow),就是“業務過程的部分或整體在計算機應用環境下的自動化”,它主要解決的是“使在多個參與者之間按照某種預定義的規則傳遞文件、資訊或任務的過程自動進行,從而實現某個預期的業務目標,或者促使此目標的實現。

2、工作流管理系統(Workflow Management System, WfMS)是一個軟體系統,它完成工作量的定義和管理,並按照在系統中預先定義好的工作流邏輯進行工作流例項的執行。工作流管理系統不是企業的業務系統,而是為企業的業務系統的執行提供了一個軟體的支撐環境。

3、常見的工作流框架有Activity、JBPM、OSWorkFlow、WorkFlow。本系列使用activiti5.13版本。

4、工作流框架底層需要有資料庫提供支援,activiti5.13版本,有23張表。JBPM4.4框架有18張表。JBPM底層使用hibernate操作資料庫。Activiti框架底層使用的mybatis操作資料庫。

Activiti介紹

Activiti5是由Alfresco軟體在2010年5月17日釋出的業務流程管理(BPM)框架,它是覆蓋了業務流程管理、工作流、服務協作等領域的一個開源的、靈活的、易擴充套件的可執行流程語言框架。Activiti基於Apache許可的開源BPM平臺,創始人Tom Baeyens是JBoss jBPM的專案架構師,它特色是提供了eclipse外掛,開發人員可以通過外掛直接繪畫出業務流程圖。 

下載與目錄結構

官網:https://www.activiti.org/  ,沒啥用,打開了也沒啥東西。直接在GitHub上下載。

GitHub:https://github.com/Activiti/Activiti

目錄結構如下:

database :提供了建表語句。

docs:該目錄包含了三種文件:javadocs、userguide、xsd。

  1. javadocs:API文件,包名按照功能模組劃分,org.activiti.engine.*。
  2. userguide:使用者手冊,包含環境配置、10分鐘快速入門以及各個功能模組的使用教程。
  3. xsd
    :包含BPMN2.0規範的XSD檔案以及Activiti擴充套件的自定義標籤XSD。

libs:開發用的jar包和原始碼包。

wars:提供了兩個例子程式。

安裝activiti流程設計器外掛

1、eclipse中安裝如下:

1.1、獲得外掛的安裝包

 

1.2、解壓安裝包,複製到eclipse中的dropins目錄中

 

1.3、重啟eclipse,勾選save選項

 

2、IDEA中安裝:具體參考此文

初始化表結構

方式1、使用activiti框架提供的建表語句

在database目錄下找到相應資料庫的建表語句,執行即可。

 

方式2、使用activiti框架的自動建表功能。activiti框架提供了和hibernate類似的自動建表功能。

建立一個java專案,匯入jar包,不知道導哪些jar包,可以到war目錄解壓示例程式。把lib目錄中的jar包拷過來即可。當然資料庫驅動包時必不可少的。

1、 不使用配置檔案(不建議)

 @Test
    public void test1(){
        //1.建立一個流程引擎配置物件
        ProcessEngineConfiguration configuration=  ProcessEngineConfiguration.createStandaloneInMemProcessEngineConfiguration();
        //設定資料來源
        configuration.setJdbcDriver("com.mysql.jdbc.Driver");
        configuration.setJdbcUrl("jdbc:mysql:///activiti_demo");
        configuration.setJdbcUsername("root");
        configuration.setJdbcPassword("123456");

        //設定自動建表
        configuration.setDatabaseSchema("true");

        //建立一個流程引擎物件,在建立流程引擎物件時會自動建表
        ProcessEngine engine= configuration.buildProcessEngine();
    }

2、使用配置檔案

 配置檔案可以到示例程式的class目錄拷貝 activiti-context.xml,修改裡面的內容即可。

配置檔案

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
    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
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

    <!--配置流程引擎配置物件-->
    <bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneInMemProcessEngineConfiguration">
        <property name="jdbcDriver"  value="com.mysql.jdbc.Driver"/>
        <property name="jdbcUrl" value="jdbc:mysql:///activiti_demo"/>
        <property name="jdbcUsername" value="root" />
        <property name="jdbcPassword" value="123456" />
        <property name="databaseSchemaUpdate" value="true"/>
    </bean>
</bean>

java程式碼

   //使用配置檔案
    @Test
    public void test2(){
        //1.建立一個流程引擎配置物件
        String resource="activiti-context.xml";
        String beanName="processEngineConfiguration";
        ProcessEngineConfiguration configuration=  ProcessEngineConfiguration.createProcessEngineConfigurationFromResource(resource,beanName);

        //建立一個流程引擎物件,在建立流程引擎物件時會自動建表
        ProcessEngine engine= configuration.buildProcessEngine();
    }

3、使用配置檔案(使用預設配置),要求配置檔名稱必須為activiti-context.xml或者activiti.cfg.xml,配置的資訊必須為

 配置檔案如下:

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
    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
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

    <!--配置流程引擎配置物件-->
    <bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneInMemProcessEngineConfiguration">
        <property name="jdbcDriver"  value="com.mysql.jdbc.Driver"/>
        <property name="jdbcUrl" value="jdbc:mysql:///activiti_demo"/>
        <property name="jdbcUsername" value="root" />
        <property name="jdbcPassword" value="123456" />
        <property name="databaseSchemaUpdate" value="true"/>
    </bean>
    <!--配置工廠,用於建立流程引擎 id必須為processEngine-->
    <bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
        <property name="processEngineConfiguration" ref="processEngineConfiguration" />
    </bean>
</bean>

java程式碼

    //使用預設配置檔案
    @Test
    public void test3(){
        ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
    }

瞭解23張表

Activiti的後臺是有資料庫的支援,所有的表都以ACT_開頭。 第二部分是表示表的用途的兩個字母標識。 用途也和服務的API對應。

  1.  ACT_RE_*: 'RE'表示repository。 這個字首的表包含了流程定義和流程靜態資源 (圖片,規則,等等)。
  2.  ACT_RU_*: 'RU'表示runtime。 這些執行時的表,包含流程例項,任務,變數,非同步任務等執行中的資料。 Activiti只在流程例項執行過程中儲存這些資料, 在流程結束時就會刪除這些記錄。 這樣執行時表可以一直很小速度很快。
  3. ACT_ID_*: 'ID'表示identity。 這些表包含身份資訊,比如使用者,組等等。
  4. ACT_HI_*: 'HI'表示history。 這些表包含歷史資料,比如歷史流程例項, 變數,任務等等。
  5. ACT_GE_*: 通用資料, 用於不同場景下。

使用框架提供的API完成流程操作

可以在專案中加入log4j,將框架執行的sql輸出到控制檯,log4j提供的日誌級別:Fatal error warn info debug trace

部署流程定義

需要先畫好流程圖

/**
     * 部署流程定義(操作資料表:act_re_deployment、act_re_procdef、act_ge_bytearray)
     */
    @Test
    public void test4() {
        // 獲得一個部署構建器物件,用於載入流程定義檔案(test1.bpmn,test.png)完成流程定義的部署
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        DeploymentBuilder builder= processEngine.getRepositoryService().createDeployment();
        // 載入流程定義檔案
        builder.addClasspathResource("process/test1.bpmn");
        builder.addClasspathResource("process/test1.png");
        // 部署流程定義
        Deployment deployment = builder.deploy();
        System.out.println(deployment.getId());
    }

查詢流程定義列表

    @Test
    public void test5() {
        //流程定義查詢物件,用於查詢act_re_procdef表
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        ProcessDefinitionQuery query = processEngine.getRepositoryService().createProcessDefinitionQuery();
        //新增查詢條件
        query.processDefinitionKey("bxlc");
        query.orderByDeploymentId().desc();
        //分頁查詢
        query.listPage(0, 10);
        List<ProcessDefinition> list = query.list();
        for (ProcessDefinition item : list) {
            System.out.print(item.getId());
        }
    }

啟動流程例項

什麼是流程例項?根據一個流程定義具體的一次執行過程就是一個流程例項,一個流程定義對應多個流程例項(一對多關係)

 為了演示:在流程圖中指定辦理人是誰,現在是寫死的,表示只能張三能提交請假申請。後面會講解如何動態指定。

    //根據流程定義的Id啟動一個流程例項(操作ACT_RU_EXECUTION、ACT_RU_TASK、ACT_HI_PROCINST、ACT_HI_ACTINST、ACT_HI_TASKINST、ACT_RU_IDENTITYLINK、ACT_HI_IDENTITYLINK表)
    @Test
    public void test6() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        String processDefinitionId="qjlc:1:104";
        ProcessInstance processInstance = processEngine.getRuntimeService().startProcessInstanceById(processDefinitionId);
        System.out.print(processInstance.getId());//201
    }

查詢個人任務列表

    @Test
    public void test7() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        TaskQuery query = processEngine.getTaskService().createTaskQuery();
        query.taskAssignee("張三");
        List<Task> list = query.list();
        for (Task item : list) {
            System.out.print(item.getId()+"==="+item.getName());//204===提交請假申請
        }
    }

辦理任務

    //辦理任務(主要操作ACT_RU_EXECUTION、ACT_RU_TASK表)
    @Test
    public void test8() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        processEngine.getTaskService().complete("204");
    }

辦理任務後,流程就走到了下一個節點,再次查詢張三個人任務列表就查不到了,此時用李四去查就可以了。

使用Activiti框架的API操作流程

/**
 * 使用Activiti框架的API操作流程
*/
public class ActivitiAPITest {
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    /**
     * 部署流程定義 方式一:讀取單個的流程定義檔案 方式二:讀取zip壓縮檔案
     */
    @Test
    public void test1() {
        DeploymentBuilder deploymentBuilder = processEngine.getRepositoryService().createDeployment();

        // 方式一:讀取單個的流程定義檔案
        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);
        deploymentBuilder.name("請假流程部署");
        Deployment deployment = deploymentBuilder.deploy();*/
    }

    /**
     * 查詢部署列表
     */
    @Test
    public void test2() {
        // 部署查詢物件,查詢表act_re_deployment
        DeploymentQuery query = processEngine.getRepositoryService().createDeploymentQuery();
        List<Deployment> list = query.list();
        for (Deployment deployment : list) {
            String id = deployment.getId();
            System.out.println(id);
        }
    }

    /**
     * 查詢流程定義列表
     */
    @Test
    public void test3() {
        // 流程定義查詢物件,查詢表act_re_procdef
        ProcessDefinitionQuery query = processEngine.getRepositoryService().createProcessDefinitionQuery();
        List<ProcessDefinition> list = query.list();
        for (ProcessDefinition pd : list) {
            System.out.println(pd.getName() + "" + pd.getId());
        }
    }

    /**
     * 刪除部署資訊
     */
    @Test
    public void test4() {
        String deploymentId = "1001";
        // processEngine.getRepositoryService().deleteDeployment(deploymentId);
        processEngine.getRepositoryService().deleteDeployment(deploymentId,true);
    }

    /**
     * 刪除流程定義(通過刪除部署資訊達到刪除流程定義的目的)
     */
    @Test
    public void test5() {
        String deploymentId = "1401";
        // processEngine.getRepositoryService().deleteDeployment(deploymentId);
        processEngine.getRepositoryService().deleteDeployment(deploymentId,
                true);
    }

    /**
     * 查詢一次部署對應的流程定義檔名稱和對應的輸入流(bpmn png)
     * 
     * @throws Exception
     */
    @Test
    public void test6() 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(new File("d:\\" + name));
             * byte[] b = new byte[1024]; int len = 0; while((len =
             * in.read(b))!=-1) { out.write(b, 0, len); } out.close();
             */
            FileUtils.copyInputStreamToFile(in, new File("d:\\" + name));
            in.close();
        }
    }

    /**
     * 獲得png檔案的輸入流
     * 
     * @throws Exception
     */
    @Test
    public void test7() throws Exception {
        String processDefinitionId = "qjlc:9:1204";
        InputStream pngInputStream = processEngine.getRepositoryService()
                .getProcessDiagram(processDefinitionId);
        FileUtils.copyInputStreamToFile(pngInputStream, new File("d:\\my.png"));
    }

    /**
     * 啟動流程例項 方式一:根據流程定義的id啟動 方式二:根據流程定義的key啟動(自動選擇最新版本的流程定義啟動流程例項)
     */
    @Test
    public void test8() {
        /*
         * String processDefinitionId = "qjlc:9:1204"; ProcessInstance
         * processInstance =
         * processEngine.getRuntimeService().startProcessInstanceById
         * (processDefinitionId ); System.out.println(processInstance.getId());
         */

        String processDefinitionKey = "qjlc";
        ProcessInstance processInstance = processEngine.getRuntimeService()
                .startProcessInstanceByKey(processDefinitionKey);
        System.out.println(processInstance.getId());
    }

    /**
     * 查詢流程例項列表,查詢act_ru_execution表
     */
    @Test
    public void test9(){
        //流程例項查詢物件,查詢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 test10(){
        String processInstanceId = "1601";
        processEngine.getRuntimeService().deleteProcessInstance(processInstanceId , "我願意");
    }

    /**
     * 查詢任務列表
     */
    @Test
    public void test11(){
        //任務查詢物件,查詢act_ru_task表
        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());
        }
    }

    /**
     * 辦理任務
     */
    @Test
    public void test12(){
        String taskId = "2902";
        processEngine.getTaskService().complete(taskId);
    }

    /**
     * 直接將流程向下執行一步
     */
    @Test
    public void test13(){
        String executionId = "2701";//流程例項id
        processEngine.getRuntimeService().signal(executionId);
    }
    
    /**
     * 查詢最新版本的流程定義列表
     */
    @Test
    public void test14(){
        ProcessDefinitionQuery query = processEngine.getRepositoryService().createProcessDefinitionQuery();
        query.orderByProcessDefinitionVersion().asc();
        List<ProcessDefinition> list = query.list();
        Map<String, ProcessDefinition> map = new HashMap<String, ProcessDefinition>();
        for (ProcessDefinition pd : list) {
            map.put(pd.getKey(), pd);
        }
        ArrayList<ProcessDefinition> lastList = new ArrayList<>(map.values());
        for (ProcessDefinition processDefinition : lastList) {
            System.out.println(processDefinition.getName() + "  "+ processDefinition.getVersion() );
        }
    }
}

Activiti框架提供的Service物件

  1. RepositoryService----操作靜態的資源(流程定義,bpmn、png)
  2. RuntimeService-----操作流程例項(啟動流程例項、查詢流程例項、結束流程例項)
  3. TaskService-----操作任務(查詢任務、辦理任務)
  4. HistoryService----操作歷史資料

Activiti框架提供的物件(和表有對應關係)

  • Deployment-----act_re_deployment
  • ProcessDefinition----act_re_procdef
  • ProcessInstance-----act_ru_execution
  • Task-----act_ru_task

使用網頁版流程設計器

1、將activiti-explorer.war複製到tomcat中

2、啟動tomcat,訪問http://lcoalhost:8080/activiti-explorer

3、使用kermit/kermit登入

4、

5、

 

 參考文件:http://www.cnblogs.com/llzgzljl/archive/2013/10/07/3356108.html

學習資源:http://www.mossle.com/index.do