亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Springboot整合Activiti操作詳解

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

版本依賴

  • 開發(fā)工具 IDEA
  • SpringBoot 2.4.5(這里我試過SpringBoot 3.1.1版本,Activiti沒有啟動,應(yīng)該是依賴沖突了,后改成了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ù)庫結(jié)構(gòu)
    #1.flase:默認(rèn)值。activiti在啟動時,對比數(shù)據(jù)庫表中保存的版本,如果沒有表或者版本不匹配,將拋出異常
    #2.true: activiti會對數(shù)據(jù)庫中所有表進(jìn)行更新操作。如果表不存在,則自動創(chuàng)建
    #3.create_drop: 在activiti啟動時創(chuàng)建表,在關(guān)閉時刪除表(必須手動關(guān)閉引擎,才能刪除表)
    #4.drop-create: 在activiti啟動時刪除原來的舊表,然后在創(chuàng)建新表(不需要手動關(guān)閉引擎)
    database-schema-update: true
    #activiti7默認(rèn)不生成歷史信息表,開啟歷史表
    db-history-used: true
    #記錄歷史等級 可配置的歷史級別有none, activity, audit, full
    #none:不保存任何的歷史數(shù)據(jù),因此,在流程執(zhí)行過程中,這是最高效的。
    #activity:級別高于none,保存流程實例與流程行為,其他數(shù)據(jù)不保存。
    #audit:除activity級別會保存的數(shù)據(jù)外,還會保存全部的流程任務(wù)及其屬性。audit為history的默認(rèn)值。
    #full:保存歷史數(shù)據(jù)的最高級別,除了會保存audit級別的數(shù)據(jù)外,還會保存其他全部流程相關(guān)的細(xì)節(jié)數(shù)據(jù),包括一些流程參數(shù)等。
    history-level: full
    #自動檢查、部署流程定義文件
    check-process-definitions: false
    # asyncExecutorActivate是指activiti在流程引擎啟動就激活A(yù)syncExecutor,異步:true-開啟(默認(rèn))、false-關(guān)閉
    async-executor-activate: true

配置文件這里注意要設(shè)置 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時,需要下載一個插件

在這里插入圖片描述

當(dāng)這個插件安裝好以后,新建文件會多一個選項

在這里插入圖片描述

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

在這里插入圖片描述

在這里插入圖片描述

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

activiti服務(wù)類進(jìn)行編寫

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;
    /**
     * 部署流程服務(wù)
     */
    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;
    }
    /**
     * 查詢用戶待完成和待認(rèn)領(lǐng)的任務(wù)
     * @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;
    }
    /**
     * 查詢用戶的待完成任務(wù)
     * @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中提供的服務(wù)類,直接注入即可。即springboot整合activiti啟動過程中,已經(jīng)在容器中自動裝配了對應(yīng)的服務(wù)類,需要的時候,僅僅需要取來用即可。如果啟動以后報錯,容器沒有自動裝配對應(yīng)的服務(wù)類,那很有可能是依賴沖突,activiti沒有正常啟動。

流程部署

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

在這里插入圖片描述

在這里插入圖片描述

流程定義

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

在這里插入圖片描述

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

在這里插入圖片描述

啟動流程

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

在這里插入圖片描述

這里要明白流程定義id和key的區(qū)別,流程定義的key是在畫流程的時候可以設(shè)置的,通過設(shè)置流程的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è)務(wù)中最好使用 流程作業(yè)類型 + 一個業(yè)務(wù)臺賬id,比如:請假申請要走審批流程, 離職申請也要走審批流程,如果只用id作為bussinessKey的話,bussinessKey就無法滿足唯一性。所以最好 前面加上作業(yè)類型。這里的map傳入的是流程圖里面的參數(shù)。

在這里插入圖片描述

傳入受理人,這里就會產(chǎn)生一個Task,就是用戶的代辦任務(wù)。

完成任務(wù)

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

受理任務(wù)

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

以上就是Springboot整合Activiti操作詳解的詳細(xì)內(nèi)容,更多關(guān)于Springboot整合Activiti的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • URLConnection發(fā)送HTTP請求的方法_動力節(jié)點Java學(xué)院整理

    URLConnection發(fā)送HTTP請求的方法_動力節(jié)點Java學(xué)院整理

    這篇文章主要介紹了URLConnection發(fā)送HTTP請求的方法,主要介紹了如何通過Java(模擬瀏覽器)發(fā)送HTTP請求,有興趣的可以了解一下
    2017-07-07
  • Spring容器注入bean的五種方法逐個解析

    Spring容器注入bean的五種方法逐個解析

    依賴注入(Dependency Injection)和控制反轉(zhuǎn)(Inversion of Control)是同一個概念。具體含義是:當(dāng)某個角色(可能是一個Java實例,調(diào)用者)需要另一個角色(另一個Java實例,被調(diào)用者)的協(xié)助時,在傳統(tǒng)的程序設(shè)計過程中,通常由調(diào)用者來創(chuàng)建被調(diào)用者的實例
    2023-02-02
  • 打包SpringBoot程序為exe的案例教程

    打包SpringBoot程序為exe的案例教程

    這篇文章主要介紹了打包SpringBoot程序為exe的案例教程,文中通過圖文講解的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-12-12
  • java利用mybatis攔截器統(tǒng)計sql執(zhí)行時間示例

    java利用mybatis攔截器統(tǒng)計sql執(zhí)行時間示例

    這篇文章主要介紹了java利用mybatis攔截器統(tǒng)計sql執(zhí)行時間示例,該攔截器攔截mybatis的query和update操作,能統(tǒng)計sql執(zhí)行時間
    2014-03-03
  • Java源碼解析阻塞隊列ArrayBlockingQueue功能簡介

    Java源碼解析阻塞隊列ArrayBlockingQueue功能簡介

    今天小編就為大家分享一篇關(guān)于Java源碼解析阻塞隊列ArrayBlockingQueue功能簡介,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • SpringMVC返回圖片的幾種方式(小結(jié))

    SpringMVC返回圖片的幾種方式(小結(jié))

    這篇文章主要介紹了SpringMVC返回圖片的幾種方式(小結(jié)),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-01-01
  • Springboot 使用具體化類和配置來縮短單元測試時間

    Springboot 使用具體化類和配置來縮短單元測試時間

    這篇文章主要介紹了Springboot 使用具體化類和配置來縮短單元測試時間,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • 如何在Java中判斷兩個Long類型是否相等

    如何在Java中判斷兩個Long類型是否相等

    這篇文章主要介紹了如何在Java中判斷兩個Long類型是否相等,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的?參考價值,需要的小伙伴可以參考一下
    2022-09-09
  • maven項目test執(zhí)行main找不到資源文件的問題及解決

    maven項目test執(zhí)行main找不到資源文件的問題及解決

    這篇文章主要介紹了maven項目test執(zhí)行main找不到資源文件的問題及解決,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • Java判斷兩個集合是否具有交集及如何獲得交集詳解

    Java判斷兩個集合是否具有交集及如何獲得交集詳解

    這篇文章主要給大家介紹了關(guān)于Java判斷兩個集合是否具有交集及如何獲得交集的相關(guān)資料,文中通過圖文以及實例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-07-07

最新評論