Activiti工作流基礎(chǔ)學(xué)習(xí)筆記

一粗井、了解工作流

工作流(Workflow)鹅心,就是“業(yè)務(wù)過(guò)程的部分或整體在計(jì)算機(jī)應(yīng)用環(huán)境下的自動(dòng)化”误阻,它主要解決的是“使在多個(gè)參與者之間按照某種預(yù)定義的規(guī)則傳遞文檔抖所、信息或任務(wù)的過(guò)程自動(dòng)進(jìn)行行拢,從而實(shí)現(xiàn)某個(gè)預(yù)期的業(yè)務(wù)目標(biāo)祖秒,或者促使此目標(biāo)的實(shí)現(xiàn)”。
工作流管理系統(tǒng)(Workflow Management System, WfMS)是一個(gè)軟件系統(tǒng),它完成工作量的定義和管理竭缝,并按照在系統(tǒng)中預(yù)先定義好的工作流邏輯進(jìn)行工作流實(shí)例的執(zhí)行房维。工作流管理系統(tǒng)不是企業(yè)的業(yè)務(wù)系統(tǒng),而是為企業(yè)的業(yè)務(wù)系統(tǒng)的運(yùn)行提供了一個(gè)軟件的支撐環(huán)境歌馍。

常見(jiàn)的工作流框架
Activity5.13握巢、JBPM4.4、OSWorkFlow松却、WorkFlow
工作流框架底層需要有數(shù)據(jù)庫(kù)提供支持暴浦,activiti5.13版本,有23張表晓锻。JBPM4.4框架底層有數(shù)據(jù)庫(kù)支持歌焦,18張表。JBPM底層使用hibernate操作數(shù)據(jù)庫(kù)砚哆。Activiti框架底層使用的mybatis操作數(shù)據(jù)庫(kù)独撇。

二、初始化表結(jié)構(gòu)

1.使用Activiti框架提供的建表語(yǔ)句

下載的Activiti框架的包中 /activiti-x.xx/database/ceate/ 目錄中提供各種數(shù)據(jù)庫(kù)的建表語(yǔ)句躁锁。

2.使用Activiti框架自動(dòng)建表

2.1 不使用配置文件
    @Test
    public void test1() {
        //    創(chuàng)建一個(gè)流程引擎配置對(duì)象
        ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration();

        //    設(shè)置數(shù)據(jù)源信息
        configuration.setJdbcDriver("com.mysql.jdbc.Driver");
        configuration.setJdbcUrl("jdbc:mysql://localhost:3306/activiti");
        configuration.setJdbcUsername("root");
        configuration.setJdbcPassword("");

        //    設(shè)置自動(dòng)建表
        configuration.setDatabaseSchemaUpdate("true");

        //    創(chuàng)建一個(gè)流程引擎對(duì)象纷铣,在創(chuàng)建流程引擎對(duì)象中會(huì)自動(dòng)建表
        ProcessEngine processEngine = configuration.buildProcessEngine();
    }
2.2 使用自定義配置文件

actitviti-context.xml (名字隨意)

    <!-- 配置流程引擎配置對(duì)象 -->
    <bean id="processEngineConfiguration"
        class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
        <property name="jdbcDriver" value="com.mysql.jdbc.Driver" />
        <property name="jdbcUrl" value="jdbc:mysql:///activiti" />
        <property name="jdbcUsername" value="root" />
        <property name="jdbcPassword" value="" />
        <property name="databaseSchemaUpdate" value="true" />
    </bean>

Test.java

    @Test
    /**
     * 使用框架提供的自動(dòng)建表(提供配置文件)
     */
    public void test2() {
        String resource = "actitviti-context.xml";//配置文件名稱(chēng)
        String beanName = "processEngineConfiguration";//配置id值
        //加載配置文件
        ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource(resource, beanName);
       //創(chuàng)建流程引擎對(duì)象
        ProcessEngine processEngine = configuration.buildProcessEngine();
    }
3.3 使用Activiti框架提供的默認(rèn)配置文件

要求配置文件名稱(chēng)必須為activiti-context.xml或者activiti.cfg.xml。

配置流程引擎配置對(duì)象的id必須為 processEngineConfiguration
創(chuàng)建流程引擎對(duì)象的id必須為processEngine
activiti-context.xml

    <!-- 配置流程引擎配置對(duì)象 -->
    <bean id="processEngineConfiguration"
        class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
        <property name="jdbcDriver" value="com.mysql.jdbc.Driver" />
        <property name="jdbcUrl" value="jdbc:mysql:///activiti" />
        <!--<property name="jdbcUrl" value="jdbc:mysql:///activiti_web" />-->
        <property name="jdbcUsername" value="root" />
        <property name="jdbcPassword" value="" />
        <property name="databaseSchemaUpdate" value="true" />
    </bean>

    <!-- 配置一個(gè)流程引擎工廠bean战转,用于創(chuàng)建流程引擎對(duì)象 -->
    <bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
        <!-- 通過(guò)set方法注入流程引擎配置對(duì)象 -->
        <property name="processEngineConfiguration" ref="processEngineConfiguration" />
    </bean>

Test.java

    @Test
    /**
     * 使用框架提供的自動(dòng)建表(使用默認(rèn)配置文件)
     */
    public void test() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    }

三搜立、了解Activiti框架中的二十三張表

Activiti的后臺(tái)是有數(shù)據(jù)庫(kù)的支持,所有的表都以ACT_開(kāi)頭槐秧。 第二部分是表示表的用途的兩個(gè)字母標(biāo)識(shí)啄踊。 用途也和服務(wù)的API對(duì)應(yīng)。

  1. ACT_RE_*: 'RE'表示repository刁标。 這個(gè)前綴的表包含了流程定義和流程靜態(tài)資源 (圖片颠通,規(guī)則,等等)膀懈。
  2. ACT_RU_*: 'RU'表示runtime顿锰。 這些運(yùn)行時(shí)的表,包含流程實(shí)例吏砂,任務(wù)撵儿,變量,異步任務(wù)狐血,等運(yùn)行中的數(shù)據(jù)淀歇。 Activiti只在流程實(shí)例執(zhí)行過(guò)程中保存這些數(shù)據(jù), 在流程結(jié)束時(shí)就會(huì)刪除這些記錄匈织。 這樣運(yùn)行時(shí)表可以一直很小速度很快浪默。
  3. ACT_ID_*: 'ID'表示identity牡直。 這些表包含身份信息,比如用戶纳决,組等等碰逸。
  4. ACT_HI_*: 'HI'表示history。 這些表包含歷史數(shù)據(jù)阔加,比如歷史流程實(shí)例饵史, 變量,任務(wù)等等胜榔。
  5. ACT_GE_*: 通用數(shù)據(jù)胳喷, 用于不同場(chǎng)景下。

四夭织、Activiti框架的基本使用

1.部署流程定義

1.1 使用Eclipse或Idea的BPMN編輯插件繪制流程圖吭露,并導(dǎo)出 流程圖.bpmn流程圖.png。(插件的安裝及使用自行百度)

2.2 使用Java代碼部署流程流程定義
Test.java

    @Test
    /**
     * 部署流程定義
     * 操作的數(shù)據(jù)表:
     *      act_re_deloyment(部署表) 部署一次 插入一條記錄
     *      act_re_procdef 可以認(rèn)為是部署表的擴(kuò)展表 流程定義表
     *      act_ge_bytearray:流程定義文件被序列化存在數(shù)據(jù)表中
     */
    public void test() {
        //使用默認(rèn)配置文件創(chuàng)建流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 獲得一個(gè)部署構(gòu)建器對(duì)象尊惰,用于加載流程定義文件(test.bpmn test.png)完成流程定義的部署
        DeploymentBuilder builder = processEngine.getRepositoryService().createDeployment();
        //   加載流程定義文件
        builder.addClasspathResource("/process/test.bpmn");
        builder.addClasspathResource("/process/test.png");
        //    部署流程定義
        Deployment deployment = builder.deploy();
    }

2. 查詢流程定義列表

    /**
     * 查詢流程定義列表
     */
    @Test
    public void test() {
        //使用默認(rèn)配置文件創(chuàng)建流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //    流程定義查詢對(duì)象讲竿,用于查詢act_re_procdef
        ProcessDefinitionQuery query = processEngine.getRepositoryService().createProcessDefinitionQuery();
        //添加過(guò)濾條件
        query.processDefinitionKey("myProcess_1");
        //    添加排序條件
        query.orderByProcessDefinitionVersion().desc();
        //添加分頁(yè)查詢
        query.listPage(0, 10);
        List<ProcessDefinition> list = query.list();
        for (ProcessDefinition pd : list) {
            System.out.println(pd.getId());
        }
    }

3.啟動(dòng)流程實(shí)例

流程實(shí)例是根據(jù)一個(gè)流程定義具體的一次執(zhí)行過(guò)程就是一個(gè)流程實(shí)例,一個(gè)流程定義對(duì)應(yīng)多個(gè)流程實(shí)例(一對(duì)多關(guān)系)。

    /**
     * 根據(jù)流程定義 啟動(dòng)一個(gè)流程實(shí)例
     * 根據(jù)流程定義的一次具體執(zhí)行過(guò)程弄屡,就是一個(gè)流程實(shí)例
     */
    @Test
    public void test() {
        //使用默認(rèn)配置文件創(chuàng)建流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        String processDefinitionId = "myProcess_1:7:1004";//流程定義id可在act_re_procdef表中查詢到
        ProcessInstance processInstance = processEngine.getRuntimeService().startProcessInstanceById(processDefinitionId);
        System.out.println(processInstance.getId());
    }

4.查詢個(gè)人任務(wù)列表

    /**
     * 查詢個(gè)人任務(wù)列表
     */
    @Test
    public void test() {
        //使用默認(rèn)配置文件創(chuàng)建流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //創(chuàng)建任務(wù)查詢
        TaskQuery taskQuery = processEngine.getTaskService().createTaskQuery();
      //添加查詢條件 辦理人為王五
        String assignee = "王五";
        taskQuery.taskAssignee(assignee);
        List<Task> list = taskQuery.list();//查詢所有
        for (Task task : list) {
            System.out.println(task.getId() + "——" + task.getName());
        }
    }

5.辦理任務(wù)

    /**
     * 辦理業(yè)務(wù)
     */
    @Test
    public void test() {
        //使用默認(rèn)配置文件創(chuàng)建流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        String taskId = "602";//任務(wù)id可在act_ru_task表中查詢到
        processEngine.getTaskService().complete(taskId);//傳入任務(wù)id辦理業(yè)務(wù)
        System.out.println("辦理成功");
    }

五题禀、Activiti提供的Service對(duì)象

在以上的代碼中有很多Servie,接下來(lái)說(shuō)明一下這些Service的區(qū)別膀捷。

RepositoryService----操作靜態(tài)的資源(流程定義投剥,bpmn、png)
RuntimeService-----操作流程實(shí)例(啟動(dòng)流程實(shí)例担孔、查詢流程實(shí)例、結(jié)束流程實(shí)例)
TaskService-----操作任務(wù)(查詢?nèi)蝿?wù)吃警、辦理任務(wù))
HistoryService----操作歷史數(shù)據(jù)

六糕篇、Activiti框架提供的對(duì)象(和表有對(duì)應(yīng)關(guān)系)

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

七、使用Activiti框架提供的網(wǎng)頁(yè)版流程設(shè)計(jì)器

1.將Activiti的包中activiti-explorer.war復(fù)制到tomcat的/webapps目錄中酌心。
2.啟動(dòng)Tomcat拌消,訪問(wèn) http://lcoalhost:8080/activiti-explorer
3.登錄。登錄賬號(hào)和密碼為:kermit

八安券、使用Activiti框架的API操作流程

1.部署流程定義的兩種方法

1.1 讀取單個(gè)的流程定義文件

    @Test
    public void test() {
        //使用默認(rèn)配置文件創(chuàng)建流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //創(chuàng)建流程部署對(duì)象
        DeploymentBuilder deploymentBuilder = processEngine.getRepositoryService().createDeployment();

        //讀取單個(gè)的流程定義文件
        deploymentBuilder.addClasspathResource("/process/test.bpmn");
        deploymentBuilder.addClasspathResource("/process/test.png");
        Deployment deployment = deploymentBuilder.deploy();//部署流程

1.2 讀取ZIP壓縮文件
將test.bpmn和test.png放到同一個(gè)zip壓縮包中墩崩。

    @Test
    public void test() {
        //使用默認(rèn)配置文件創(chuàng)建流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //創(chuàng)建流程部署對(duì)象
        DeploymentBuilder deploymentBuilder = processEngine.getRepositoryService().createDeployment();

        //讀取ZIP壓縮文件
        //讀取資源文件
        ZipInputStream zipInputStream = new ZipInputStream(this.getClass().getClassLoader().getResourceAsStream("/process/process.zip"));
        deploymentBuilder.addZipInputStream(zipInputStream);
        deploymentBuilder.name("請(qǐng)假流程部署");//設(shè)置流程定義名稱(chēng)
        Deployment deployment1 = deploymentBuilder.deploy();//部署流程
    }

2.查詢流程部署列表 (act_re_deployment表)

    @Test
    public void test() {
        //使用默認(rèn)配置文件創(chuàng)建流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //部署查詢對(duì)象,查詢act_re_deployment 部署表
        DeploymentQuery deploymentQuery = processEngine.getRepositoryService().createDeploymentQuery();
        List<Deployment> list = deploymentQuery.list();
        for (Deployment deployment : list) {
            String id = deployment.getId();
            System.out.println(id);
        }
    }

3.刪除部署信息

    @Test
    public void test() {
        //使用默認(rèn)配置文件創(chuàng)建流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        String deloymentId = "7504"; //流程部署id  在act_re_deployment表中
        //deleteDeployment有兩個(gè)參數(shù) 第一個(gè)刪除 部署的內(nèi)容的id侯勉,第二個(gè)是否級(jí)聯(lián)刪除鹦筹,默認(rèn)為false
        processEngine.getRepositoryService().deleteDeployment(deloymentId, true);
    }

4.刪除流程定義(通過(guò)刪除部署信息達(dá)到刪除流程定義的目的)

    @Test
    public void test() {
        //使用默認(rèn)配置文件創(chuàng)建流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        String deloymentId = "1001";
        //deleteDeployment有兩個(gè)參數(shù) 第一個(gè)刪除 部署的內(nèi)容的id,第二個(gè)是否級(jí)聯(lián)刪除址貌,默認(rèn)為false
        processEngine.getRepositoryService().deleteDeployment(deloymentId, true);
    }

5.查詢流程定義列表

    @Test
    public void test() {
        //使用默認(rèn)配置文件創(chuàng)建流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //流程定義查詢對(duì)象铐拐,查詢表act_re_procdef
        ProcessDefinitionQuery processDefinitionQuery = processEngine.getRepositoryService().createProcessDefinitionQuery();
        List<ProcessDefinition> list = processDefinitionQuery.list();
        for (ProcessDefinition pd : list) {
            System.out.println(pd.getName() + "———" + pd.getId());
        }
    }

6.查詢一次部署對(duì)應(yīng)的流程定義文件和對(duì)應(yīng)的輸入流(bpmn徘键,png)

 @Test
    public void test() throws IOException {
        //使用默認(rèn)配置文件創(chuàng)建流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        String deploymentId = "901";
        List<String> list = processEngine.getRepositoryService().getDeploymentResourceNames(deploymentId);
        for (String name : list) {
            System.out.println(name);
            InputStream inputStream = processEngine.getRepositoryService().getResourceAsStream(deploymentId, name);
            //將文件保存到本地磁盤(pán)
         org.apache.commons.io.FileUtils.copyInputStreamToFile(inputStream, new File("d:\\" + name));
            inputStream.close();
        }
    }

7.獲得png文件的輸入流

    @Test
    public void test() throws IOException {
        //使用默認(rèn)配置文件創(chuàng)建流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        String processDefinitionId = "myProcess_1:6:904";
        InputStream PngInputStream = processEngine.getRepositoryService().getProcessDiagram(processDefinitionId);
        FileUtils.copyInputStreamToFile(PngInputStream, new File("d:\\my.png"));
    }

8.啟動(dòng)流程實(shí)例的兩種方法

8.1 方式一:根據(jù)流程定義的id啟動(dòng)

@Test
    public void test() {
        //使用默認(rèn)配置文件創(chuàng)建流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //方式一:根據(jù)流程定義的id啟動(dòng)
       String processDefinitionId = "myProcess_1:6:904";
        ProcessInstance processInstance = processEngine.getRuntimeService().startProcessInstanceById(processDefinitionId);
        System.out.println(processInstance.getId());
}

8.2 方式二:根據(jù)流程定義的key啟動(dòng)(自動(dòng)選擇最新版本的流程定義啟動(dòng)流程實(shí)例)

    @Test
    public void test() {
        //使用默認(rèn)配置文件創(chuàng)建流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //方式二:根據(jù)流程定義的key啟動(dòng)(自動(dòng)選擇最新版本的流程定義啟動(dòng)流程實(shí)例)
        String processDefinitionKey = "myProcess_1";
        ProcessInstance processInstance = processEngine.getRuntimeService().startProcessInstanceByKey(processDefinitionKey);
        System.out.println(processInstance.getId());
    }

9.查詢流程實(shí)例列表,查詢act_ru_execution表

    @Test
    public void test() {
        //使用默認(rèn)配置文件創(chuàng)建流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //流程實(shí)例查詢對(duì)象遍蟋,查詢act_ru_execution表
        ProcessInstanceQuery query = processEngine.getRuntimeService().createProcessInstanceQuery();
        query.processDefinitionKey("myProcess_1");
        query.orderByProcessDefinitionId().desc();
        query.listPage(0, 3);
        List<ProcessInstance> list = query.list();
        for (ProcessInstance pi : list) {
            System.out.println(pi.getId() + "--" + pi.getActivityId());
        }
    }

10.結(jié)束流程實(shí)例

操作的表:act_re_excution,act_ru_task

    @Test
    public void test() {
        //使用默認(rèn)配置文件創(chuàng)建流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        String processInstanceId = "1601";
        processEngine.getRuntimeService().deleteProcessInstance(processInstanceId, "不想要了");
    }

11.查詢?nèi)蝿?wù)列表

    @Test
    public void test() {
        //使用默認(rèn)配置文件創(chuàng)建流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //任務(wù)查詢對(duì)象吹害,查詢?nèi)蝿?wù)表 act_ru_task表
        TaskQuery query = processEngine.getTaskService().createTaskQuery();
        //按照辦理人進(jìn)行過(guò)濾
        String assignee = "李四";
        query.taskAssignee(assignee);
        query.orderByTaskCreateTime().desc();
        List<Task> list = query.list();
        for (Task task : list) {
            System.out.println(task.getId());
        }
    }

12.辦理任務(wù)

    @Test
    public void test() {
        //使用默認(rèn)配置文件創(chuàng)建流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        String taskId = "1404";
        processEngine.getTaskService().complete(taskId);
    }

13.直接將流程向下執(zhí)行一步

    @Test
    public void test() {
        //使用默認(rèn)配置文件創(chuàng)建流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        String executionId = "1401"; //流程實(shí)例id
        processEngine.getRuntimeService().signal(executionId);
    }

14.查詢最新版本的流程定義列表

    @Test
    public void test() {
        //使用默認(rèn)配置文件創(chuàng)建流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        ProcessDefinitionQuery query = processEngine.getRepositoryService().createProcessDefinitionQuery();
        query.orderByProcessDefinitionVersion().asc();
        List<ProcessDefinition> list = query.list();
        Map<String, ProcessDefinition> map = new HashMap<>();
        for (ProcessDefinition pd : list) {
            map.put(pd.getKey(),pd);
        }
        System.out.println(map);
    }

15.流程的修改

流程的修改:添加新的流程版本,如果已經(jīng)在執(zhí)行的流程虚青,按照原來(lái)的流程繼續(xù)執(zhí)行它呀。新的流程按照最新版本進(jìn)行執(zhí)行。

16.歷史數(shù)據(jù)查詢

16.1 查詢歷史流程實(shí)例列表
查詢歷史流程實(shí)例列表 act_hi_procinst

    @Test
    public void test() {
        //使用默認(rèn)配置文件創(chuàng)建流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        HistoricProcessInstanceQuery query = processEngine.getHistoryService().createHistoricProcessInstanceQuery();
        List<HistoricProcessInstance> list = query.list();
        for (HistoricProcessInstance hi : list) {
            System.out.println(hi.getId());
        }
    }

16.2 查詢歷史活動(dòng)數(shù)據(jù)
查詢歷史活動(dòng)數(shù)據(jù) act_hi_actinst 包括任務(wù)和事件

    @Test
    public void test() {
        //使用默認(rèn)配置文件創(chuàng)建流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        HistoricActivityInstanceQuery query = processEngine.getHistoryService().createHistoricActivityInstanceQuery();
        //按照流程實(shí)例排序
        query.orderByProcessInstanceId().desc();
        query.orderByHistoricActivityInstanceEndTime().asc();
        List<HistoricActivityInstance> list = query.list();
        for (HistoricActivityInstance hi : list) {
            System.out.println(hi.getActivityId() + "——" + hi.getActivityName() + "——" + hi.getActivityType());
        }
    }

16.3 查詢歷史任務(wù)數(shù)據(jù)
查詢歷史任務(wù)數(shù)據(jù) act_hi_taskinst 單純的只有任務(wù)

    @Test
    public void test() {
        //使用默認(rèn)配置文件創(chuàng)建流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        HistoricTaskInstanceQuery query = processEngine.getHistoryService().createHistoricTaskInstanceQuery();
        query.orderByProcessInstanceId().asc();
        query.orderByHistoricTaskInstanceEndTime().asc();
        List<HistoricTaskInstance> list = query.list();
        for (HistoricTaskInstance hi:list){
            System.out.println(hi.getAssignee()+"——"+hi.getName()+"——"+hi.getStartTime());
        }
    }

九棒厘、流程變量

在流程執(zhí)行或者任務(wù)執(zhí)行的過(guò)程中纵穿,用于設(shè)置和獲取變量,使用流程變量在流程傳遞的過(guò)程中傳遞業(yè)務(wù)參數(shù)绊谭。

對(duì)應(yīng)的表:
act_ru_variable:正在執(zhí)行的流程變量表
act_hi_varinst:流程變量歷史表


流程變量圖解

流程變量.png

1.設(shè)置流程變量

1.1 在啟動(dòng)流程實(shí)例時(shí)設(shè)置

    @Test
    public void test() {
        //使用默認(rèn)配置文件創(chuàng)建流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        String processDefinitionKey = "variable";
        Map<String, Object> variables = new HashMap<>();
        variables.put("key1", "value1");
        variables.put("key2", 200);
        ProcessInstance processInstance = processEngine.getRuntimeService().startProcessInstanceByKey(processDefinitionKey, variables);
        System.out.println(processInstance.getId());
    }

1.2 在辦理任務(wù)時(shí)設(shè)置流程變量

    @Test
    public void test() {
        //使用默認(rèn)配置文件創(chuàng)建流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        String taskId = "1206";
        Map<String, Object> variables = new HashMap<>();
        variables.put("user", new User(1, "小王"));
        processEngine.getTaskService().complete(taskId, variables);
    }

1.3 使用RuntimeService的方法設(shè)置

    @Test
    public void test() {
        //使用默認(rèn)配置文件創(chuàng)建流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        String excutionId = "601";//流程實(shí)例Id
        String variableName = "key3";
        String value = "value3";
        processEngine.getRuntimeService().setVariable(excutionId, variableName, value);
    }

1.4 使用TaskService的方法設(shè)置

    @Test
    public void test() {
        //使用默認(rèn)配置文件創(chuàng)建流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        String taskId = "704";
        Map<String, Object> variables = new HashMap<>();
        variables.put("key4", 400);
        variables.put("k5", "v5");
        processEngine.getTaskService().setVariables(taskId, variables);
    }


2.流程變量支持的類(lèi)型

Jdk中提供的數(shù)據(jù)類(lèi)型(String政恍、Integer、List 达传、Map…)
自定義的實(shí)體類(lèi)(要求實(shí)現(xiàn)序列化接口)篙耗,在variable表中只存bytearray_id 實(shí)例化內(nèi)容存在bytearray表中。

3.獲取流程變量

3.1 使用RuntimeService的方法獲取

    @Test
    public void test() {
        //使用默認(rèn)配置文件創(chuàng)建流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        String executionId = "1201";
        Map<String, Object> variables = processEngine.getRuntimeService().getVariables(executionId);
        System.out.println(variables);
        Set<String> set = variables.keySet();//key2 key1 user
        for (String key : set) {
            Object val = variables.get(key);
            System.out.println(key + "=" + val);
        }

        //根據(jù)一個(gè)key獲得一個(gè)value
        Object value = processEngine.getRuntimeService().getVariable(executionId, "user");
        System.out.println(value);

        Collection<String> variableNames = new ArrayList<>();
        variableNames.add("key2");
        variableNames.add("user");
        Map<String, Object> map = processEngine.getRuntimeService().getVariables(executionId, variableNames);
        System.out.println(map);

3.2 使用TaskService的方法獲取

    @Test
    public void test() {
        //使用默認(rèn)配置文件創(chuàng)建流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        String taskId = "1305";
        Map<String, Object> variables = processEngine.getTaskService().getVariables(taskId);
    }


十宪赶、任務(wù)的類(lèi)型

1.個(gè)人任務(wù)

由某一個(gè)負(fù)責(zé)辦理宗弯,在任務(wù)表中通過(guò)assignee字段記錄。

2.公共任務(wù)(組任務(wù))

當(dāng)前的任務(wù)可以由多個(gè)人其中的某一個(gè)人辦理搂妻, 可以在設(shè)計(jì)流程圖時(shí)指定多個(gè)辦理人蒙保。Candidate Users 候選用戶


公共任務(wù)圖示.png

2.1 查詢公共任務(wù)列表

    @Test
    public void test() {
        //使用默認(rèn)配置文件創(chuàng)建流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        TaskQuery query = processEngine.getTaskService().createTaskQuery();
        //    根據(jù)候選人過(guò)濾
        String candidateUser = "李四";
        query.taskCandidateUser(candidateUser);
        List<Task> list = query.list();
        for (Task task:list){
            System.out.println(task.getName());
        }
    }

2.2 拾取公共任務(wù)(將公共任務(wù)變?yōu)閭€(gè)人任務(wù))

    @Test
    public void test(){
        //使用默認(rèn)配置文件創(chuàng)建流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        String taskId="1602";
        String userId="王五";
        processEngine.getTaskService().claim(taskId,userId);
    }

2.3 退回任務(wù)(將個(gè)人任務(wù)重新變?yōu)楣踩蝿?wù))

    @Test
    public void test(){
        //使用默認(rèn)配置文件創(chuàng)建流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        String taskId="1602";
        processEngine.getTaskService().setAssignee(taskId,null);
    }


3.接受任務(wù)

接收任務(wù)不是由某個(gè)人負(fù)責(zé)辦理,通過(guò)signal方法讓流程執(zhí)行的
接收任務(wù)圖示.png
    /**
     * 處理接收任務(wù)
     */
    @Test
    public void test() {
        //使用默認(rèn)配置文件創(chuàng)建流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        String excutionId = "2501";
        processEngine.getRuntimeService().signal(excutionId);
    }


十一欲主、監(jiān)聽(tīng)器(Listener)

1.執(zhí)行監(jiān)聽(tīng)器

監(jiān)聽(tīng)流程實(shí)例的事件

第一步:按照框架的規(guī)則編寫(xiě)監(jiān)聽(tīng)器類(lèi)

import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.ExecutionListener;

/**
 * @author Hiseico
 * @create 2018-06-07 16:41
 * @desc 自定義執(zhí)行監(jiān)聽(tīng)器
 **/
public class MyExcutionListener implements ExecutionListener {
    //當(dāng)監(jiān)聽(tīng)事件發(fā)生時(shí)執(zhí)行此方法
    @Override
    public void notify(DelegateExecution delegateExecution) throws Exception {
        System.out.println("自定義的監(jiān)聽(tīng)器執(zhí)行睬塌。闸盔。。2");
    }
}

第二步:設(shè)計(jì)流程圖,注冊(cè)監(jiān)聽(tīng)器類(lèi)


執(zhí)行監(jiān)聽(tīng)器設(shè)置圖示.png

第三步:?jiǎn)?dòng)流程實(shí)例违孝,Activiti框架通過(guò)反射調(diào)用監(jiān)聽(tīng)器類(lèi)

2.任務(wù)監(jiān)聽(tīng)器

監(jiān)聽(tīng)任務(wù)事件

第一步:按照activiti框架的規(guī)則編寫(xiě)一個(gè)任務(wù)監(jiān)聽(tīng)器類(lèi)

import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.TaskListener;

import java.util.Set;

/**
 * @author Hiseico
 * @create 2018-06-07 17:10
 * @desc 自定義任務(wù)監(jiān)聽(tīng)器
 **/
public class MyTaskListener implements TaskListener {
    /**
     * 監(jiān)聽(tīng)任務(wù)事件
     *
     * @param delegateTask
     */
    @Override
    public void notify(DelegateTask delegateTask) {
        //任務(wù)辦理人
        String assignee = delegateTask.getAssignee();
        //任務(wù)名稱(chēng)
        String eventName = delegateTask.getEventName();
        //事件名稱(chēng)
        String name = delegateTask.getName();
        //流程實(shí)例Id
        String processInstanceId = delegateTask.getProcessInstanceId();
        //獲取當(dāng)前流程實(shí)例范圍內(nèi)的所有流程變量的名字
        Set<String> variableNames = delegateTask.getVariableNames();
        for (String key : variableNames) {
            Object value = delegateTask.getVariable(key);
            System.out.println(key + " = " + value);
        }
        System.out.println("一個(gè)["+name+"]任務(wù)被創(chuàng)建了矿辽,由["+assignee+"]負(fù)責(zé)辦理");
    }
}

第二步:注冊(cè)監(jiān)聽(tīng)類(lèi)


注冊(cè)任務(wù)監(jiān)聽(tīng)器圖示.png

第三步:辦理任務(wù)芭毙,由框架通過(guò)反射調(diào)用監(jiān)聽(tīng)器類(lèi)

十二嘱丢、網(wǎng)關(guān)

1.排他網(wǎng)關(guān)(ExclusiveGateway)

用來(lái)在流程中實(shí)現(xiàn)決策。當(dāng)流程執(zhí)行到排他網(wǎng)關(guān)伟桅,所有數(shù)據(jù)就會(huì)被執(zhí)行一遍敞掘,滿足條件的就會(huì)讓流程繼續(xù)運(yùn)行。需要注意的是:排他網(wǎng)關(guān)只會(huì)選擇一條滿足條件的執(zhí)行楣铁。

第一步:設(shè)計(jì)流程圖玖雁,使用排他網(wǎng)關(guān)


設(shè)置排他網(wǎng)關(guān)圖示.png

第二步:執(zhí)行流程,由框架根據(jù)設(shè)置的流程變量選擇執(zhí)行其中的一個(gè)分支民褂,在分支的線上設(shè)置參數(shù):Condition:#{bxje>200}

第三步:辦理業(yè)務(wù)

    /**
     * 辦理任務(wù)茄菊,設(shè)置流程變量
     */
    @Test
    public void test() {
        String taskId = "802";
        Map<String, Object> variables = new HashMap<>();
        variables.put("bxje",600);//排他網(wǎng)關(guān)會(huì)自動(dòng)判斷 bxje 變量的值疯潭,選擇執(zhí)行分支
        processEngine.getTaskService().complete(taskId,variables);
    }


2.并行網(wǎng)關(guān)(ParallelGateway)

它允許將流程分成多條分支,也可以把多條分支匯聚成一條面殖。

分支:經(jīng)過(guò)并行網(wǎng)關(guān)的所有流竖哩,都會(huì)并行執(zhí)行

匯聚:等所有流都到達(dá)并行網(wǎng)關(guān)之后,流程才會(huì)通過(guò)并行網(wǎng)關(guān)脊僚。

并行網(wǎng)關(guān)相叁,沒(méi)有條件判斷。流程通過(guò)網(wǎng)關(guān)之后辽幌,有幾條分支增淹,就會(huì)有幾個(gè)執(zhí)行對(duì)象同時(shí)執(zhí)行。需要注意的是:并行網(wǎng)關(guān)一定是成對(duì)出現(xiàn)的乌企,有分支也有匯聚虑润。

并行網(wǎng)關(guān)圖示.png


十三、Spring整合Activiti

第一步:提供spring配置文件加酵,配置數(shù)據(jù)源拳喻、事務(wù)管理器、流程引擎配置對(duì)象猪腕、流程引擎對(duì)象
appplicationContext.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">
    <!--配置數(shù)據(jù)源-->
    <bean id="ds" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql:///activiti"/>
        <property name="username" value="root"/>
        <property name="password" value=""/>
    </bean>

    <!--事務(wù)管理器-->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="ds"/>
    </bean>

    <!--配置一個(gè)Spring提供的對(duì)象冗澈,用于創(chuàng)建一個(gè)流程引擎配置對(duì)象-->
    <bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
        <property name="transactionManager" ref="transactionManager"/>
        <property name="dataSource" ref="ds"/>
        <!--自動(dòng)建表的配置-->
        <property name="databaseSchemaUpdate" value="true"/>
    </bean>

    <!--創(chuàng)建流程引擎對(duì)象-->
    <bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
        <property name="processEngineConfiguration" ref="processEngineConfiguration"/>
    </bean>
</beans>

第二步:在Java程序中讀取spring配置文件,創(chuàng)建spring工廠陋葡,獲取流程引擎對(duì)象

public class SpringActivitiTest {
    @Test
    public void test() {
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring/applicationContext.xml");
       ProcessEngine processEngine = (ProcessEngine) applicationContext.getBean("processEngine");
        DeploymentBuilder deploymentBuilder = processEngine.getRepositoryService().createDeployment();
        deploymentBuilder.addClasspathResource("spring/variable.bpmn");
        Deployment deployment = deploymentBuilder.deploy();
    }
}





到此Activiti框架的基礎(chǔ)筆記就先整理到這里亚亲,本筆記用作學(xué)習(xí)完Activiti框架后復(fù)習(xí)使用,不適用于Activiti框架入門(mén)教程腐缤,不喜勿噴捌归。

轉(zhuǎn)載請(qǐng)注明出處及作者。

Create By Hiseico

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末岭粤,一起剝皮案震驚了整個(gè)濱河市陨溅,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌绍在,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件雹有,死亡現(xiàn)場(chǎng)離奇詭異偿渡,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)霸奕,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)溜宽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人质帅,你說(shuō)我怎么就攤上這事适揉×粼埽” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵嫉嘀,是天一觀的道長(zhǎng)炼邀。 經(jīng)常有香客問(wèn)我,道長(zhǎng)剪侮,這世上最難降的妖魔是什么拭宁? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮瓣俯,結(jié)果婚禮上杰标,老公的妹妹穿的比我還像新娘。我一直安慰自己彩匕,他們只是感情好腔剂,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著驼仪,像睡著了一般掸犬。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上谅畅,一...
    開(kāi)封第一講書(shū)人閱讀 51,737評(píng)論 1 305
  • 那天登渣,我揣著相機(jī)與錄音,去河邊找鬼毡泻。 笑死胜茧,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的仇味。 我是一名探鬼主播呻顽,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼丹墨!你這毒婦竟也來(lái)了廊遍?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤贩挣,失蹤者是張志新(化名)和其女友劉穎喉前,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體王财,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡卵迂,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了绒净。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片见咒。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖挂疆,靈堂內(nèi)的尸體忽然破棺而出改览,到底是詐尸還是另有隱情下翎,我是刑警寧澤,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布宝当,位于F島的核電站视事,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏今妄。R本人自食惡果不足惜郑口,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望盾鳞。 院中可真熱鬧犬性,春花似錦、人聲如沸腾仅。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)推励。三九已至鹤耍,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間验辞,已是汗流浹背稿黄。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留跌造,地道東北人杆怕。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像壳贪,于是被迫代替她去往敵國(guó)和親陵珍。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容