最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Springboot整合Activiti操作詳解

 更新時間:2023年07月06日 09:33:33   作者:啊幾  
這篇文章主要給大家詳細介紹了Springboot整合Activiti的操作流程,文中流程步驟和代碼示例介紹的非常詳細,具有一定的參考價值,需要的朋友可以參考下

版本依賴

  • 開發(fā)工具 IDEA
  • SpringBoot 2.4.5(這里我試過SpringBoot 3.1.1版本,Activiti沒有啟動,應該是依賴沖突了,后改成了2.4.5版本)
  • Activiti 7.1.0.M6

父項目pom.xml

    <dependencyManagement>
        <dependencies>
            <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-parent -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-parent</artifactId>
                <version>2.4.5</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- https://mvnrepository.com/artifact/org.activiti.dependencies/activiti-dependencies -->
            <dependency>
                <groupId>org.activiti.dependencies</groupId>
                <artifactId>activiti-dependencies</artifactId>
                <version>7.1.0.M6</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

子項目pom.xml

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
    </dependencies>

配置文件

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.zaxxer.hikari.HikariDataSource
    username: root
    password: 111111
    url: jdbc:mysql://127.0.0.1:3306/activiti?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8&useSSL=false&useInformationSchema=true
    hikari:
      #連接池做大連接數(shù)
      maximum-pool-size: 30
      #連接池空閑連接最小數(shù)量
      #minimum-idle: 10
      #允許連接在連接池中閑置最長時間
      #idle-timeout: 30000
      #池中連接最長生命周期
      max-lifetime: 120000
      #等待來自池的連接的最大毫秒數(shù)
      connection-timeout: 30000
  activiti:
    #自動更新數(shù)據(jù)庫結構
    #1.flase:默認值。activiti在啟動時,對比數(shù)據(jù)庫表中保存的版本,如果沒有表或者版本不匹配,將拋出異常
    #2.true: activiti會對數(shù)據(jù)庫中所有表進行更新操作。如果表不存在,則自動創(chuàng)建
    #3.create_drop: 在activiti啟動時創(chuàng)建表,在關閉時刪除表(必須手動關閉引擎,才能刪除表)
    #4.drop-create: 在activiti啟動時刪除原來的舊表,然后在創(chuàng)建新表(不需要手動關閉引擎)
    database-schema-update: true
    #activiti7默認不生成歷史信息表,開啟歷史表
    db-history-used: true
    #記錄歷史等級 可配置的歷史級別有none, activity, audit, full
    #none:不保存任何的歷史數(shù)據(jù),因此,在流程執(zhí)行過程中,這是最高效的。
    #activity:級別高于none,保存流程實例與流程行為,其他數(shù)據(jù)不保存。
    #audit:除activity級別會保存的數(shù)據(jù)外,還會保存全部的流程任務及其屬性。audit為history的默認值。
    #full:保存歷史數(shù)據(jù)的最高級別,除了會保存audit級別的數(shù)據(jù)外,還會保存其他全部流程相關的細節(jié)數(shù)據(jù),包括一些流程參數(shù)等。
    history-level: full
    #自動檢查、部署流程定義文件
    check-process-definitions: false
    # asyncExecutorActivate是指activiti在流程引擎啟動就激活AsyncExecutor,異步:true-開啟(默認)、false-關閉
    async-executor-activate: true

配置文件這里注意要設置 database-sechema-update的屬性為true,才會自動創(chuàng)建表。

需要注意的問題

在初次啟動時可能會報錯,報錯如下:

Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.security.core.userdetails.UserDetailsService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoMatchingBeanFound(DefaultListableBeanFactory.java:1790)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1346)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1300)
	at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887)
	at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791)
	... 142 more

這里是需要一個UserDetailsService的Bean,需要創(chuàng)建一個類去實現(xiàn)UserDetailsService接口

UserDetailsServiceImpl.class

package org.example.config;
import org.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Component;
@Component
public class UserDetailsServiceImpl implements UserDetailsService {
    @Autowired
    UserService userService;
    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        return userService.findOneUserByName(username);
    }
}

UserService.class

package org.example.service;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;
import org.springframework.security.core.userdetails.User;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class UserService {
    public User findOneUserByName(String username){
        List<GrantedAuthority> authorities = AuthorityUtils.commaSeparatedStringToAuthorityList("admin");
        return new User(username,"",authorities);
    }
}

啟動成功后,數(shù)據(jù)庫會生成25張表

在這里插入圖片描述

畫流程圖

在使用IDEA時,需要下載一個插件

在這里插入圖片描述

當這個插件安裝好以后,新建文件會多一個選項

在這里插入圖片描述

新建的xml文件可以通過view BPMN Diagram,轉化為圖表操作

在這里插入圖片描述

在這里插入圖片描述

如何通過圖表操作畫流程這里就不說了,可以自己摸索看看。

activiti服務類進行編寫

package org.example.service;
import org.activiti.engine.*;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.DeploymentQuery;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.repository.ProcessDefinitionQuery;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
@Service
public class ActivitiService {
    @Autowired
    RepositoryService repositoryService;
    @Autowired
    RuntimeService runtimeService;
    @Autowired
    TaskService taskService;
    @Autowired
    HistoryService historyService;
    /**
     * 部署流程服務
     */
    public void deployProcess(){
        String file = "bpmn/test.bpmn20.xml";
        Deployment deployment = repositoryService.createDeployment()
                .addClasspathResource(file)
                .name("流程部署測試")
                .deploy();
        System.out.println("流程部署名稱:"+deployment.getName());
    }
    /**
     * 查詢所有部署的流程定義
     * @return
     */
    public List<ProcessDefinition> getAllProcessDefinition(){
        ProcessDefinitionQuery query = repositoryService.createProcessDefinitionQuery();
        return query.orderByProcessDefinitionVersion().desc().list();
    }
    /**
     * 查詢所有的部署
     * @return
     */
    public List<Deployment> getAllDeployment(){
        DeploymentQuery query = repositoryService.createDeploymentQuery();
        return query.list();
    }
    /**
     * 查詢所有流程實例
     * @return
     */
    public List<ProcessInstance> getAllProcessInstance(){
        List<ProcessInstance> list = runtimeService.createProcessInstanceQuery().list();
        return list;
    }
    public List<Task> getAllProcessTask(){
        List<Task> list = taskService.createTaskQuery().list();
        return list;
    }
    /**
     * 查詢用戶待完成和待認領的任務
     * @param username
     * @return
     */
    public List<Task> getAllProcessTaskByCandidateOrAssigned(String username){
        List<Task> list = taskService.createTaskQuery().taskCandidateOrAssigned(username).list();
        return list;
    }
    public List<Task> getAllProcessTaskByCandidate(String username){
        List<Task> list = taskService.createTaskQuery().taskCandidateUser(username).list();
        return list;
    }
    /**
     * 查詢用戶的待完成任務
     * @param username
     * @return
     */
    public List<Task> getAllProcessTaskByAssigned(String username){
        List<Task> list = taskService.createTaskQuery().taskAssignee(username).list();
        return list;
    }
    public void complateTask(Task task, Map<String, Object> map){
        taskService.complete(task.getId(),map);
    }
    public void complateTask(Task task){
        taskService.complete(task.getId());
    }
    public void claimTask(Task task,String username){
        taskService.claim(task.getId(),username);
    }
    public ProcessInstance startProcess(String processDefinitionKey,String businessKey,Map<String,Object> map){
        return runtimeService.startProcessInstanceById(processDefinitionKey,businessKey,map);
    }
    public String getProcessDefinitionXml(String processDefinitionId) {
        ProcessDefinition processDefinition = repositoryService.getProcessDefinition(processDefinitionId);
        String resourceName = processDefinition.getResourceName();
        InputStream resourceAsStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), resourceName);
        try {
            return IOUtils.toString(resourceAsStream, StandardCharsets.UTF_8);
        } catch (IOException e) {
            // handle exception
        }
        return null;
    }
    public List<HistoricProcessInstance> getHistoryByBusinessKey(String businessKey){
        List<HistoricProcessInstance> list = historyService.createHistoricProcessInstanceQuery().processInstanceBusinessKey(businessKey).list();
        return list;
    }
}

在這里插入圖片描述

上圖是,如果需要使用activiti中提供的服務類,直接注入即可。即springboot整合activiti啟動過程中,已經在容器中自動裝配了對應的服務類,需要的時候,僅僅需要取來用即可。如果啟動以后報錯,容器沒有自動裝配對應的服務類,那很有可能是依賴沖突,activiti沒有正常啟動。

流程部署

流程部署有多種方式,這是通過資源路徑部署的,也可以通過壓縮包的形式部署流程。那就需要用到DeploymentBuilderaddZipInputStream方法,這里也是用到了設計模式中的建造者模式。

在這里插入圖片描述

在這里插入圖片描述

流程定義

這是一個查詢所有部署的流程定義的方法

在這里插入圖片描述

當一個流程部署以后,就會生成一個流程定義,流程圖的xml信息也會存入數(shù)據(jù)庫。每次部署流程圖都會生成一個新的流程定義。

在這里插入圖片描述

啟動流程

啟動流程可以通過流程定義的id或者key,如果想通過流程定義的id啟動一個流程可以使用startProcessInstanceById方法,如果想通過流程定義的key啟動一個流程可以使用startProcessInstanceByKey方法。

在這里插入圖片描述

這里要明白流程定義id和key的區(qū)別,流程定義的key是在畫流程的時候可以設置的,通過設置流程的id,這個就是流程的key。

在這里插入圖片描述

在這里插入圖片描述

那流程的id呢,這是部署以后在數(shù)據(jù)庫表的id。可以根據(jù)需要自行選擇啟動流程的方法。

流程實例

查詢所有啟動的流程實例

在這里插入圖片描述

每次開始一個流程以后,就會生成一個流程實例。通過這個方法可以查看所有的流程實例。

測試流程

package org.example;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.assertj.core.util.DateUtil;
import org.example.common.PrintUtil;
import org.example.entity.User;
import org.example.service.ActivitiService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.*;
@SpringBootTest
public class SpringBootApplicationTest {
    @Resource
    DataSource dataSource;
    @Autowired
    ActivitiService activitiService;
    @Test
    void context() throws SQLException {
        System.out.println(dataSource.getConnection());
    }
    @Test
    public void deployProcess(){
        activitiService.deployProcess();
    }
    @Test
    public void TestStartProcess(){
        ProcessDefinition processDefinition = activitiService.getAllProcessDefinition().get(0);
        String bussinessKey = this.getClass().getSimpleName();
        Map<String , Object> map = new HashMap<String , Object>();
        map.put("creator","Echo");
        activitiService.startProcess(processDefinition.getId(),bussinessKey,map);
    }
    @Test
    public void findAllDeployment(){
        List<Deployment> list = activitiService.getAllDeployment();
        PrintUtil.printTable(list);
    }
    @Test
    public void findAllProcessDefinition(){
        List<ProcessDefinition> list = activitiService.getAllProcessDefinition();
        PrintUtil.printTable(list);
    }
    @Test
    public void findAllProcessInstance(){
        List<ProcessInstance> list = activitiService.getAllProcessInstance();
        PrintUtil.printTable(list);
    }
    @Test
    public void findAllProcessTask(){
        List<Task> list = activitiService.getAllProcessTask();
        PrintUtil.printTable(list);
    }
    @Test
    public void findTaskByUserId(){
        String userId = "keaizp";
        List<Task> list = activitiService.getAllProcessTaskByCandidateOrAssigned(userId);
        PrintUtil.printTable(list);
    }
    @Test
    public void claimTask(){
        String userId="keaizp";
        List<Task> list = activitiService.getAllProcessTaskByCandidate(userId);
        PrintUtil.printTable(list);
        activitiService.claimTask(list.get(0),userId);
        list = activitiService.getAllProcessTaskByCandidate("zengpei");
        PrintUtil.printTable(list);
    }
    @Test
    public void complateUserTask(){
        String userId = "Echo";
        List<Task> list = activitiService.getAllProcessTaskByAssigned(userId);
        List<String> candidateUsers = new ArrayList<String>();
        candidateUsers.add("keaizp");
        candidateUsers.add("zengpei");
        Map<String,Object> map = new HashMap<String,Object>();
        map.put("approver",candidateUsers);
        activitiService.complateTask(list.get(0),map);
    }
    @Test
    public void processDefinitionXml(){
        List<ProcessDefinition> list = activitiService.getAllProcessDefinition();
        String xmlStr = activitiService.getProcessDefinitionXml(list.get(0).getId());
        System.out.println(xmlStr);
    }
    @Test
    public void findHistoryByBusinessKey(){
        List<HistoricProcessInstance> list = activitiService.getHistoryByBusinessKey("2023-07-02T22:45:45");
        PrintUtil.printTable(list);
    }
    @Test
    public void printTest(){
        List<User> users = new ArrayList<>();
        users.add(new User("keaizpeeeeeeeee",24,"male"));
        users.add(new User("Echo",24,"male"));
        users.add(new User("nick",24,"male"));
        users.add(new User("amy",24,"male"));
        PrintUtil.printTableFixed(users,16);
    }
}

啟動流程

在這里插入圖片描述

這里我用的是一個格式化的日期做bussinessKey,實際業(yè)務中最好使用 流程作業(yè)類型 + 一個業(yè)務臺賬id,比如:請假申請要走審批流程, 離職申請也要走審批流程,如果只用id作為bussinessKey的話,bussinessKey就無法滿足唯一性。所以最好 前面加上作業(yè)類型。這里的map傳入的是流程圖里面的參數(shù)。

在這里插入圖片描述

傳入受理人,這里就會產生一個Task,就是用戶的代辦任務。

完成任務

在這里插入圖片描述
當用戶登錄系統(tǒng)的時候,應該給用戶提示,用戶有未完成的代辦事項,然后給出用戶代辦事項列表,做完一切以后,就是完成用戶任務,這個時候,可以傳入下一流程節(jié)點參與任務的人,當然你也可以傳入幾個候選人,candidate Users就是 候選人。可以傳入一個用戶id的列表,然后這幾個人就會收到可以受理的任務,可以選擇是否接受該任務。只要接受了任務,其他候選人就無法再接受此任務,同時這個任務的Assignee就會設置成受理人的id

受理任務

在這里插入圖片描述
因為用戶“keaizp”成為了候選者,他就可以看到自己可以受理的這個任務,用claim方法就可以受理該任務,當受理任務完成以后,再去看看另外一名候選者的受理任務,會發(fā)現(xiàn)已經沒有待受理的任務了。

以上就是Springboot整合Activiti操作詳解的詳細內容,更多關于Springboot整合Activiti的資料請關注腳本之家其它相關文章!

相關文章

  • Intellij IDEA實現(xiàn)SpringBoot項目多端口啟動的兩種方法

    Intellij IDEA實現(xiàn)SpringBoot項目多端口啟動的兩種方法

    有時候使用springboot項目時遇到這樣一種情況,用一個項目需要復制很多遍進行測試,除了端口號不同以外,沒有任何不同。遇到這種情況怎么辦呢?這時候可以使用Intellij IDEA解決
    2018-06-06
  • maven自動將源碼打包并發(fā)布的實現(xiàn)步驟

    maven自動將源碼打包并發(fā)布的實現(xiàn)步驟

    maven-source-plugin 提供項目自動將源碼打包并發(fā)布的功能,在需要發(fā)布源碼項目的 pom.xml 文件中添加即可,本文就來介紹一下如何設置,感興趣的可以了解一下
    2023-11-11
  • Java讀取文本文件的各種方法

    Java讀取文本文件的各種方法

    這篇文章主要介紹了Java讀取文本文件的各種方法,在 Java 中有多種方法可以讀取純文本文件,例如你可以使用FileReader、BufferedReader或Scanner來讀取文本文件,感興趣的小伙伴和小編一起進入文章了解更多內容吧,希望能幫助到大家
    2021-11-11
  • @Async注解的使用以及注解失效問題的解決

    @Async注解的使用以及注解失效問題的解決

    在Spring框架中,@Async注解用于聲明異步任務,可以修飾類或方法,使用@Async時,必須確保方法為public,且類為Spring管理的Bean,啟用異步任務需要在主類上添加@EnableAsync注解,默認線程池為SimpleAsyncTaskExecutor
    2024-09-09
  • Spring context:component-scan的使用及說明

    Spring context:component-scan的使用及說明

    這篇文章主要介紹了Spring context:component-scan的使用及說明,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • 統(tǒng)一返回JsonResult踩坑的記錄

    統(tǒng)一返回JsonResult踩坑的記錄

    這篇文章主要介紹了統(tǒng)一返回JsonResult踩坑的記錄,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2025-06-06
  • Java中Hutool克隆功能的使用

    Java中Hutool克隆功能的使用

    本文主要介紹了Java中Hutool克隆功能的使用,cn.hutool.core.clone.Cloneable?是Hutool中提供的一個接口,用于支持對象的深度克隆操作,下面就一起來介紹一下
    2024-04-04
  • Java?volatile關鍵字特性講解下篇

    Java?volatile關鍵字特性講解下篇

    JMM要求保證可見性、原子性、有序性,volatile可以保證其中的兩個,本篇文章具體驗證volatile的可見性,不原子性和禁重排,同時解決volatile的不保證原子性,讓代碼具有原子性
    2022-12-12
  • SpringBoot整合RabbitMQ實現(xiàn)六種工作模式的示例

    SpringBoot整合RabbitMQ實現(xiàn)六種工作模式的示例

    這篇文章主要介紹了SpringBoot整合RabbitMQ實現(xiàn)六種工作模式,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-07-07
  • 詳解JAVA中轉義字符

    詳解JAVA中轉義字符

    本篇文章主要介紹了詳解JAVA中轉義字符,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-08-08

最新評論

太仆寺旗| 安达市| 中山市| 繁峙县| 平度市| 安陆市| 宁安市| 太仓市| 乌兰县| 郁南县| 北票市| 宜川县| 鄂尔多斯市| 潢川县| 襄汾县| 丰县| 中卫市| 衡阳市| 昌平区| 广州市| 罗城| 蓬莱市| 中山市| 黄平县| 高尔夫| 汝州市| 平昌县| 砚山县| 灵丘县| 三门县| 淮阳县| 垦利县| 仙游县| 团风县| 龙州县| 丰顺县| 福建省| 土默特右旗| 德保县| 郎溪县| 白河县|