spring boot 集成activiti

項目結構如上圖,

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.megalith</groupId>
    <artifactId>security_simple</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>security_simple</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <pagehelper.version>1.1.0</pagehelper.version>
        <mybatis.generator.version>1.3.2</mybatis.generator.version>
        <fastjson.version>1.2.31</fastjson.version>
        <jackson.version>2.9.7</jackson.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.11</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
           <!--  <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions> -->
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
   <!--   <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jetty</artifactId>
        </dependency> -->
<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <!-- aop -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <!-- json處理 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>${fastjson.version}</version>
        </dependency>

        <!-- jackson json begin -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-core</artifactId>
            <version>${jackson.version}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <version>${jackson.version}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>${jackson.version}</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.module</groupId>
            <artifactId>jackson-module-jaxb-annotations</artifactId>
            <version>${jackson.version}</version>
        </dependency>
        <!-- jackson json end -->
        <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-lang3 -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.3.2</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.uuid</groupId>
            <artifactId>java-uuid-generator</artifactId>
            <version>3.1.3</version>
        </dependency>


        <!-- druid datasource -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.27</version>
        </dependency>
        <!-- mybatis -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.3.0</version>
        </dependency>
        <!--mybatis代碼生成器 -->
        <dependency>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-core</artifactId>
            <version>${mybatis.generator.version}</version>
        </dependency>
        <!-- bean驗證 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>

        <!-- mysql驅動 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!-- spring boot 開發工具 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>
        <!-- 測試 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <!--spring-security-oauth2 begin-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.security.oauth.boot</groupId>
            <artifactId>spring-security-oauth2-autoconfigure</artifactId>
            <version>2.0.6.RELEASE</version>
        </dependency>
        <!--spring-security-oauth2 end-->
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


</project>
 

ActivitiConfiguration是activiti的配置類

package activitiPro;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import javax.sql.DataSource;

import org.activiti.designer.test.test;
import org.activiti.engine.HistoryService;
import org.activiti.engine.IdentityService;
import org.activiti.engine.ManagementService;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.spring.SpringProcessEngineConfiguration;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;

import com.alibaba.druid.pool.DruidDataSource;

@Configuration
public class ActivitiConfiguration {
    private static final Logger log = LogManager.getLogger(ActivitiConfiguration.class);
    @Autowired
    private TestService testService;
     
     
    @Bean(name = "activitiDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.activiti")
    public DataSource activitiDataSource(){
        log.info("activitiDataSource 初始化...");
        return new DruidDataSource();
    }
    @Bean
    public PlatformTransactionManager txManager() {
        return new DataSourceTransactionManager(activitiDataSource());
    }
    @Bean
    public ProcessEngine processEngine() throws IOException {
  
        SpringProcessEngineConfiguration configuration = new SpringProcessEngineConfiguration();
    //自動部署已有的流程文件
    Resource[] resources = new PathMatchingResourcePatternResolver().getResources(ResourceLoader.CLASSPATH_URL_PREFIX + "diagrams/*.bpmn");
    configuration.setTransactionManager(txManager());
    configuration.setDataSource(activitiDataSource());
    configuration.setDatabaseSchemaUpdate("true");
    configuration.setDeploymentResources(resources);
    configuration.setDbIdentityUsed(false);
 
    
    Map<Object, Object>beans=new HashMap<Object, Object>();
    beans.put("testService",testService);
    configuration.setBeans(beans);   

   return configuration.buildProcessEngine();
}

@Bean
public RepositoryService repositoryService(ProcessEngine processEngine) {
    return processEngine.getRepositoryService();
}

@Bean
public RuntimeService runtimeService(ProcessEngine processEngine) {
    return processEngine.getRuntimeService();
}

@Bean
public TaskService taskService(ProcessEngine processEngine) {
    return processEngine.getTaskService();
}

@Bean
public HistoryService historyService(ProcessEngine processEngine) {
    return processEngine.getHistoryService();
}

@Bean
public ManagementService managementService(ProcessEngine processEngine) {
    return processEngine.getManagementService();
}

@Bean
public IdentityService identityService(ProcessEngine processEngine) {
    return processEngine.getIdentityService();
}
}

 

configuration.setBeans(beans);   //如果流程設計中需要使用${}或者#{}表達式,就需要把這個bean進行暴露,如果不進行暴露則報未知標識符錯誤

如果使用spring則在配置文件中設置:

<bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
  ...
  <property name="beans">
    <map>
      <entry key="printer" value-ref="printer" />
    </map>
  </property>
</bean>

  <bean id="printer" class="org.activiti.examples.spring.Printer" />

測試中 :

 ProcessInstance  pi=    runtimeService.startProcessInstanceByKey("myProcess");  //標識啓動流程,一般前端填寫表達時進行調用後端這句話進行啓動

同時會在流程表中穿件記錄

流程執行過程中是根據流程id查詢流程狀態和執行流程。

如下:
            List<Task> task = taskService.createTaskQuery().processInstanceId(pi.getId()).list(); //查詢流程狀態
            taskService.complete(task.get(0).getId());//執行流程

只有執行了流程,流程纔會流轉到下一步


            List<Task> task1 = taskService.createTaskQuery().processInstanceId(pi.getId()).list();//查詢流程狀態
            System.out.println(task1.get(0).getAssignee());
            askService.complete(task1.get(0).getId());//執行流程

以此類推

   TaskQuery taskQuery = taskService.createTaskQuery().taskCandidateOrAssigned(userId);//根據人查詢自己的任務

流程啓動之後會在流程表act_ru_execution存儲一條記錄,

流程執行之後會修改act_ru_execution表中ACT_ID_字段,對應流程任務id,如下圖

 

同時在流程任務表中存儲流程任務信息

如果流程任務有對應的候選人會在對應act_ru_identitylink表中產生候選人任務對應數據

流程執行完之後會清空act_ru_*表中數據,產生歷史數據

 

 

判斷

可以通過 

     Map<String,Object>pa=new HashMap<String, Object>();
             pa.put("type",0);
             ProcessInstance  pi=    runtimeService.startProcessInstanceByKey("myProcess",pa);

進行參數設置,

或者在流程執行時執行

taskService.complete(task.get(0).getId(),pa);

開發中發現使用

(排他網管)進行判斷,

 

紅框中的配置和之上一樣,代碼寫法也一樣。

 

事件監聽 定義一個類實現TaskListener

public class MyStakLinster  implements TaskListener{

    @Override
    public void notify(DelegateTask delegateTask) {  

//通過代理對象可以實現各種設置
        delegateTask.setAssignee("kk");
        
        
    }

}

 

然後在流程圖中配置上這個類,就可以了。

 

首先是我們已經對Activiti流程的開啓有了瞭解之後,在進行下文

流程中用到最多的就是用戶任務了,包括誰辦理,什麼時候辦理,辦理結果是什麼,辦理歷史等等

 

下文先介紹下用戶任務的辦理相關操作

 

用戶任務分類:

分爲4中狀態:未簽收/待辦理、已簽收/辦理中、運行中/辦理中、已完成/已辦結

 

首先,我們要了解下 TaskService 這個服務的作用:

1、查詢分配給用戶或組的任務

2、創建獨立運行任務。這些任務與流程實例無關。

3、手工設置任務的執行者,或者這些用戶通過何種方式與任務關聯。

4、認領並完成一個任務。認領意味着一個人期望成爲任務的執行者, 即這個用戶會完成這個任務。完成意味着“做這個任務要求的事情”。 通常來說會有很多種處理形式。

 

狀態:

通過TaskService來獲得任務

 

API簡述

從類 org.activiti.engine.impl.ServiceImpl 繼承的字段

所有已實現的接口:TaskService

 

TaskService taskService = processEngine.getTaskService();

 

//這邊我定義了幾個通用 變量

//String userId = "Ypp";

//String userGroup = new String["Ypp1","Ypp101"];

 

 

1、未簽收/待辦理

 那麼流程開啓之後,如何能讓下一個辦理人取得待辦任務呢?

 通過下面幾種的方法,將取得指定簽收人/辦理人的待辦數據

 //單人待簽收/待辦理

 List<Task> tasks = taskService.createTaskQuery().taskCandidateUser(userId).list();

 

 //用戶組待簽收/待辦理

 List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup(userGroup).list();

 

 //進行簽收操作,也就是將要接收辦理這個任務

 //這邊可以使用循環,也可以通過其他方法,常用的是先加載一個任務待辦列表到頁面上,簽收任務傳遞後臺一個taskId

 //task.getId() = taskId 

 taskService.claim(task.getId(), userId);//完成簽收這個時候就任務Task的Assignee屬性就有了值

 

 

 //已經簽收過的任務列表,某種意義上我理解爲真正的辦理人

 List<Task> tasks = taskService.createTaskQuery().taskAssignee(userId).list();

 

2、辦理

 通過 1、未簽收/待辦理 中取得需要辦理的任務Task之後 

 //調用 task.getId() = taskId 完成任務的辦理,taskService服務自動流轉到下一個辦理節點

 taskService.complete(task.getId());

 

 //taskService.complete()方法 提供了重載,提供了3種方式供你選擇

 complete(String taskId)

 complete(String taskId, Map<String,Object> variables)  

 complete(String taskId, Map<String,Object> variables, boolean localScope) 

 

 如果更深的瞭解如何流轉的可以查看源碼

 

 ---------------------------------------------------------------------------

 插一下

 任務並不一定要先簽收再辦理,可以直接到待辦理中,而不是待簽收中

 可以把

 taskService.claim(task.getId(), userId);方法

 替換爲

 setAssignee(String taskId, String userId) 

 

 經過以上步驟,任務已經在 辦理中狀態了

 

3、已完成/已辦結

 任務的已完成(調用過complete方法)是指當前待辦的任務狀態,而非整個流程實例的完成狀態

 流程中數據使用到 historyService 服務

 //查詢指定用戶發起的流程 (流程歷史 用戶發起 )

 //finished  完成的流程  

 //unfinish  還在運行中的流程

 List<HistoricActivityInstance> hais = 下面的3中方法

 historyService.createHistoricProcessInstanceQuery().finished().startedBy(name).orderByProcessInstanceStartTime().desc().listPage(firstResult, maxResults);

 //查詢指定用戶參與的流程信息 (流程歷史  用戶參與 )

 List hpis = historyService.createHistoricProcessInstanceQuery().involvedUser(name).orderByProcessInstanceStartTime().desc().listPage(firstResult, maxResults);

 //查詢指定流程的任務流轉路徑 (流程歷史 任務 流轉 路經)

 historyService.createHistoricTaskInstanceQuery().processInstanceId(processInstanceId).orderByHistoricTaskInstanceEndTime().asc().list();

 

 //查看流程是否完整的運行完畢方法也有好幾種

 for (HistoricActivityInstance hai : hais) {

//如果下面的方法返回不是空,那就是已辦結

hai.getEndTime()

 }

 //查看ACT_RU_TASK表

 Long long = taskService.createTaskQuery().processInstanceId("processInstanceId").taskId("taskId").count();

 //如果long爲空,那麼也是辦結了

 taskService.createTaskQuery()查詢條件是可選的

 可以是

 taskService.createTaskQuery().processInstanceId("processInstanceId")

 taskService.createTaskQuery().taskId("taskId")

 或者其他更多條件

 

總結:

//流程在流轉中對於當前辦理人/組和簽收人/組來說,都是可以進行動態調整變化的

//需要對程序進行特殊處理,添加監聽或者其他方法

 

 

//得到用戶組待簽收

    TaskService taskService = processEngine.getTaskService();

//單人待簽收

//List<Task> tasks = taskService.createTaskQuery().taskCandidateUser(userId).list();

    List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup(userGroup).list();

    for (Task task : tasks) {

      // 簽收

      taskService.claim(task.getId(), userId);

    }

 

    //得到用戶待辦

    tasks = taskService.createTaskQuery().taskAssignee(userId).list();

    for (Task task : tasks) {

 //辦理

      taskService.complete(task.getId());

    }

 

    //順便查看歷史看看

    HistoryService historyService = processEngine.getHistoryService();

    HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(procId).singleResult();

可以參考http://www.mossle.com/docs/activiti/index.html#springExpressions

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章