Activiti7整合Springboot使用记录

作者:冰之杍 时间:2022-11-11 06:17:24 

0.Springboot项目创建

通过https://start.spring.io/生成纯净的一个springboot工程

1.引入Activiti相关依赖


<dependency>
   <groupId>org.activiti</groupId>
   <artifactId>activiti-spring-boot-starter</artifactId>
   <version>7.1.0.M6</version>
</dependency>

2.启动工程并创建activiti数据库

##activiti7中使用spring security,因此启动工程前,需要加入2个文件支持,2个文件的代码如下:


package cn.gzsendi.activitidemotest.config;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.provisioning.InMemoryUserDetailsManager;

@Configuration
public class ActivitiConfiguration {

private Logger logger = LoggerFactory.getLogger(ActivitiConfiguration.class);

@Bean(name = "userDetailsService")
   public UserDetailsService myUserDetailsService() {

InMemoryUserDetailsManager inMemoryUserDetailsManager = new InMemoryUserDetailsManager();

//用户
       String[][] usersGroupsAndRoles = {
               {"hefy", "123456", "ROLE_ACTIVITI_USER"},
               {"liujh", "123456", "ROLE_ACTIVITI_ADMIN"},
               {"liuky", "123456", "ROLE_ACTIVITI_USER"},
               {"admin", "123456", "ROLE_ACTIVITI_ADMIN"},
       };

for (String[] user : usersGroupsAndRoles) {
           List<String> authoritiesStrings = Arrays.asList(Arrays.copyOfRange(user, 2, user.length));
           logger.info("> Registering new user: " + user[0] + " with the following Authorities[" + authoritiesStrings + "]");
           inMemoryUserDetailsManager.createUser(new User(user[0], passwordEncoder().encode(user[1]),
                   authoritiesStrings.stream().map(s -> new SimpleGrantedAuthority(s)).collect(Collectors.toList())));
       }

return inMemoryUserDetailsManager;

}

@Bean
   public PasswordEncoder passwordEncoder() {
       return new BCryptPasswordEncoder();
   }

}

package cn.gzsendi.activitidemotest.utils;

import java.util.Collection;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextImpl;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

@Component
public class SecurityUtil {

@Autowired
   @Qualifier("userDetailsService")
   private UserDetailsService userDetailsService;

public void logInAs(String username) {

UserDetails user = userDetailsService.loadUserByUsername(username);

if (user == null) {
           throw new IllegalStateException("User " + username + " doesn't exist, please provide a valid user");
       }

SecurityContextHolder.setContext(new SecurityContextImpl(new Authentication() {
           @Override
           public Collection<? extends GrantedAuthority> getAuthorities() {
               return user.getAuthorities();
           }

@Override
           public Object getCredentials() {
               return user.getPassword();
           }

@Override
           public Object getDetails() {
               return user;
           }

@Override
           public Object getPrincipal() {
               return user;
           }

@Override
           public boolean isAuthenticated() {
               return true;
           }

@Override
           public void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {

}

@Override
           public String getName() {
               return user.getUsername();
           }
       }));

org.activiti.engine.impl.identity.Authentication.setAuthenticatedUserId(username);
   }

}

##加入activiti7的配置


server.port=8080
server.servlet.context-path=/activitidemotest

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/activitidemo?useSSL=false&useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&allowMultiQueries=true
spring.datasource.username=root
spring.datasource.password=123456

spring.activiti.database-schema-update=true
spring.activiti.db-history-used=true
spring.activiti.history-level=full
spring.activiti.check-process-definitions=false
spring.activiti.deployment-mode=never-fail
spring.activiti.process-definition-location-prefix=classpath:/process/

##启动springboot工程,让系统启动时帮我们建好25张表 2.安装Activiti插件(设计器) ##Idea

file->settings->plugins,然后找actiBPM进行安装。
Activiti7整合Springboot使用记录

##流程图中乱码问题先提前设置防止:

修改idea64.exe.vmoptions文件,在文件中加上如下,然后重启Idea

-Dfile.encoding=utf-8

##进行流程设计

File->new->BpmnFile
Activiti7整合Springboot使用记录
Activiti7整合Springboot使用记录

设计好后,修改Process1.bpmn成Process1.xml,然后右键export file导出成Process1.jpg,再将Process1.bpmn修改成Process1.bpmn20.xml,最后将2个文件放在process文件夹
Activiti7整合Springboot使用记录

3.流程部署

使用activiti提供的api把流程定义内容存储起来,Activiti执行把流程定义内容存储在数据库中。


package cn.gzsendi.activitidemotest;

/**
* Created by jxlhl on 2021/8/18.
*/

import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.DeploymentBuilder;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootJunitTest {

//得到RepositoryService实例
   @Autowired
   private RepositoryService repositoryService;

//0.流程部署,单个文件部署方式
   @Test
   public void testDeployment(){

//使用RepositoryService进行部署
       DeploymentBuilder builder = repositoryService.createDeployment();
       builder.addClasspathResource("process/Process1.bpmn20.xml");
       builder.addClasspathResource("process/Process1.jpg");
       builder.name("first_activiti_process");
       Deployment deployment = builder.deploy();

//输出部署信息
       System.out.println("流程部署id:" + deployment.getId());
       System.out.println("流程部署名称:" + deployment.getName());

//流程部署id:125098e1-ffd9-11eb-8847-02004c4f4f50
       //流程部署名称:first_activiti_process

}

}

执行此操作后activiti会将上边代码中指定的bpmn20文件和图片文件保存在activiti数据库。

流程定义部署后操作activiti的3张表

Activiti7整合Springboot使用记录
Activiti7整合Springboot使用记录
Activiti7整合Springboot使用记录

4.流程实例启动

启动一个流程实例表示开始一次业务流程的运行


 //1.流程实例启动
   @Test
   public void testStartProcess(){
       //根据流程定义Id启动流程
       ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("myProcess_1");

//输出实例信息
       System.out.println("流程定义id:" + processInstance.getProcessDefinitionId());
       System.out.println("流程实例id:" + processInstance.getId());
       System.out.println("当前活动Id:" + processInstance.getActivityId());

//流程定义id:myProcess_1:1:12702ed4-ffd9-11eb-8847-02004c4f4f50
       //流程实例id:a9b162aa-ffda-11eb-bad1-02004c4f4f50
       //当前活动Id:null

}

流程实例启动,将操作以下几个数据库表


act_hi_actinst 流程实例执行历史
act_hi_identitylink 流程的参与用户历史信息
act_hi_procinst 流程实例历史信息
act_hi_taskinst 流程任务历史信息
act_ru_execution 流程执行信息
act_ru_identitylink 流程的参与用户信息
act_ru_task 任务信息

5.任务查询

流程启动后,任务的负责人就可以查询自己当前需要处理的任务,查询出来的任务都是该用户的待办任务。


//2.任务查询
   //流程启动后,任务的负责人就可以查询自己当前需要处理的任务,查询出来的任务都是该用户的待办任务。
   @Test
   public void testFindPersonalTaskList() {
       //任务负责人
       String assignee = "liuky";

//根据流程key 和 任务负责人 查询任务
       List<Task> list = taskService.createTaskQuery()
               .processDefinitionKey("myProcess_1")
               .taskAssignee(assignee)
               .list();

for (Task task : list) {

System.out.println("流程实例id:" + task.getProcessInstanceId());
           System.out.println("任务id:" + task.getId());
           System.out.println("任务负责人:" + task.getAssignee());
           System.out.println("任务名称:" + task.getName());

}

//流程实例id:a9b162aa-ffda-11eb-bad1-02004c4f4f50
       //任务id:a9b5815e-ffda-11eb-bad1-02004c4f4f50
       //任务负责人:liuky
       //任务名称:提交申请

}

6. 完成任务


@Test
   public void completTask(){

//根据流程key和任务的负责人查询任务并选择其中的一个任务处理,这里用的
       //是singleResult返回一条,真实环境中是通过步骤5中查询出所有的任务,然后在页面上选择一个任务进行处理.
       Task task = taskService.createTaskQuery()
               .processDefinitionKey("myProcess_1") //流程Key
               .taskAssignee("liuky")  //要查询的负责人
               .singleResult();

//完成任务,参数:任务id
       taskService.complete(task.getId());

}

7.流程结束,或流程流转过程中的历史信息查询


  //流程结束,或流程流转过程中的历史信息查询
   @Test
   public void findHistoryInfo(){

//获取 actinst表的查询对象
       HistoricActivityInstanceQuery instanceQuery = historyService.createHistoricActivityInstanceQuery();
       //查询 actinst表,条件:根据 InstanceId 查询
       instanceQuery.processInstanceId("fb5b7674-ffde-11eb-91f8-02004c4f4f50");
       //增加排序操作,orderByHistoricActivityInstanceStartTime 根据开始时间排序 asc 升序
       instanceQuery.orderByHistoricActivityInstanceStartTime().asc();
       //查询所有内容
       List<HistoricActivityInstance> activityInstanceList = instanceQuery.list();
       //输出结果
       for (HistoricActivityInstance hi : activityInstanceList) {

System.out.println("");
           System.out.println("===================-===============");
           System.out.println(hi.getStartTime());
           System.out.println(hi.getAssignee());
           System.out.println(hi.getActivityId());
           System.out.println(hi.getActivityName());
           System.out.println(hi.getProcessDefinitionId());
           System.out.println(hi.getProcessInstanceId());
           System.out.println("===================-===============");
           System.out.println("");

}
   }

8.其他Api测试

8.1 流程定义信息查询

查询流程相关信息,包含流程定义,流程部署,流程定义版本


@Test
   public void queryProcessDefinition(){

//得到ProcessDefinitionQuery对象
       ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();

//查询出当前所有的流程定义
       List<ProcessDefinition> definitionList = processDefinitionQuery.processDefinitionKey("myProcess_1")
               .orderByProcessDefinitionVersion()
               .desc()
               .list();

//打印结果
       for (ProcessDefinition processDefinition : definitionList) {
           System.out.println("流程定义 id="+processDefinition.getId());
           System.out.println("流程定义 name="+processDefinition.getName());
           System.out.println("流程定义 key="+processDefinition.getKey());
           System.out.println("流程定义 Version="+processDefinition.getVersion());
           System.out.println("流程部署ID ="+processDefinition.getDeploymentId());
       }

}

8.2 删除流程


 //删除流程
   @Test
   public void deleteDeployment(){

String deploymentId = "125098e1-ffd9-11eb-8847-02004c4f4f50";

//删除流程定义,如果该流程定义已有流程实例启动则删除时出错
       repositoryService.deleteDeployment(deploymentId);

//设置true 级联删除流程定义,即使该流程有流程实例启动也可以删除,设置为false非级别删除方式,如果流程
       //repositoryService.deleteDeployment(deploymentId, true);

}

9.demo源码下载

github: https://github.com/jxlhljh/activitidemotest.git
gitee: https://gitee.com/jxlhljh/activitidemotest.git

来源:https://blog.csdn.net/jxlhljh/article/details/119775872

标签:Springboot,Activiti7
0
投稿

猜你喜欢

  • 如何用C#找出数组中只出现了一次的数字

    2021-06-15 15:42:56
  • java中maven下载和安装步骤说明

    2022-03-05 23:07:59
  • C# WinForm制作登录界面的实现步骤

    2022-09-06 18:32:54
  • 浅谈java中String与StringBuffer的不同

    2021-11-24 11:54:12
  • C#实现简单聊天程序的方法

    2022-01-02 22:31:20
  • SpringBoot搭配AOP实现自定义注解

    2022-04-07 01:21:59
  • Android中生成、使用Json数据实例

    2023-02-04 15:01:24
  • 使用ViewPager实现左右循环滑动及滑动跳转

    2023-04-12 20:42:43
  • 利用Spring boot+LogBack+MDC实现链路追踪

    2023-10-03 16:02:53
  • 详解SpringMVC实现图片上传以及该注意的小细节

    2022-04-29 08:34:30
  • 浅谈SpringMVC请求映射handler源码解读

    2022-09-11 14:37:36
  • C#实现窗体全屏的两种方法

    2021-10-06 19:14:04
  • java io文件操作删除文件或文件夹的7种方法

    2022-08-09 13:29:21
  • java各种类型对象占用内存情况分析

    2023-08-22 10:32:05
  • java 生成xml并转为字符串的方法

    2023-01-07 08:27:30
  • 解析Kotlin JSON格式

    2021-07-16 08:09:35
  • SpringBoot+Redis实现数据字典的方法

    2022-08-03 14:22:29
  • C语言图书管理系统课程设计

    2021-10-09 14:09:48
  • Spring Boot应用监控的实战教程

    2022-03-02 18:17:09
  • Android提醒微技巧你真的了解Dialog、Toast和Snackbar吗

    2023-03-08 14:15:44
  • asp之家 软件编程 m.aspxhome.com