• springboot2整合activiti7具体步骤


    写在前面

    需要提前了解的内容有 springboot、springSecurity、activiti基本使用

    关于activiti

    Activiti项目是一项新的基于Apache许可的开源BPM平台,从基础开始构建,旨在提供支持新的BPMN 2.0标准,包括支持对象管理组(OMG),面对新技术的机遇,诸如互操作性和云架构,提供技术实现。

    activiti主要应用场景

    需要动态地改变流程的业务流程场景。例如请假流程、项目审批流程等。

    正题

    第一步:

    新建一个springboot项目,引入activiti-spring-boot-starter和你所使用的数据库驱动器。本文采用Mysql 8.

    读者也可以直接复制下面的pom文件

    <?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.3.3.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>pers.lbf</groupId>
    <artifactId>springboot-activiti</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>springboot-activiti</name>
    <description>Demo project for Spring Boot</description>

    <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
    </properties>

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

    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
    <exclusions>
    <exclusion>
    <groupId>org.junit.vintage</groupId>
    <artifactId>junit-vintage-engine</artifactId>
    </exclusion>
    </exclusions>
    </dependency>

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

    <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.12</version>
    </dependency>

    <dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.3.2</version>
    </dependency>


    <dependency>
    <groupId>org.activiti</groupId>
    <artifactId>activiti-spring-boot-starter</artifactId>
    <version>7.0.0.Beta2</version>
    </dependency>


    </dependencies>

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

    </project>


    第二步,修改application.yml配置文件

    spring:
      datasource:
        url: jdbc:mysql://127.0.0.1:3306/你的数据库?userSSL=false&serverTimezone=GMT%2B8
        username: root
        password: 你的密码
        driver-class-name: com.mysql.cj.jdbc.Driver
     

    activiti:

    database-schema-update: true
        db-history-used: true
        history-level: audit

    第三步,添加springSecurity的相关配置。

    因为activiti7与springboot整合之后,默认情况下集成了springSecurity框架,所以我们需要配置一下springSecurity。本文的核心不在springSecurity,所以这一步将通过添加一个工具类的方式来完成。

     1 package pers.lbf.springbootactiviti.utils;
     2 
     3 import org.springframework.beans.factory.annotation.Autowired;
     4 import org.springframework.security.core.Authentication;
     5 import org.springframework.security.core.GrantedAuthority;
     6 import org.springframework.security.core.context.SecurityContextHolder;
     7 import org.springframework.security.core.context.SecurityContextImpl;
     8 import org.springframework.security.core.userdetails.UserDetails;
     9 import org.springframework.security.core.userdetails.UserDetailsService;
    10 import org.springframework.stereotype.Component;
    11 
    12 import javax.security.auth.Subject;
    13 import javax.vecmath.Tuple2d;
    14 import java.util.Collection;
    15 
    16 /**
    17  * @author 赖柄沣 bingfengdev@aliyun.com
    18  * @date 2020-08-18 11:27:31
    19  * @version 1.0
    20  */
    21 @Component
    22 public class SecurityUtil {
    23 
    24     @Autowired
    25     private UserDetailsService userDetailsService;
    26 
    27     
    28 
    29     public void logInAs(String username) {
    30 
    31         UserDetails user = userDetailsService.loadUserByUsername(username);
    32         if (user == null) {
    33             throw new IllegalStateException("User " + username + " doesn't exist, please provide a valid user");
    34         }
    35 
    36         Authentication authentication = new Authentication() {
    37            
    38             @Override
    39             public String getName() {
    40                 
    41                 return user.getUsername();
    42             }
    43 
    44             @Override
    45             public boolean implies(Subject subject) {
    46                 return false;
    47             }
    48 
    49             @Override
    50             public Collection<? extends GrantedAuthority> getAuthorities() {
    51                 return user.getAuthorities();
    52             }
    53 
    54             @Override
    55             public Object getCredentials()
    56             {
    57                 return user.getPassword();
    58             }
    59 
    60             @Override
    61             public Object getDetails() {
    62                 
    63                 return user;
    64             }
    65 
    66             @Override
    67             public Object getPrincipal() {
    68                 
    69                 return user;
    70             }
    71 
    72             @Override
    73             public boolean isAuthenticated() {
    74                 return true;
    75             }
    76 
    77             @Override
    78             public void setAuthenticated(boolean b) throws IllegalArgumentException {
    79 
    80             }
    81         };
    82 
    83         SecurityContextImpl securityContext = new SecurityContextImpl();
    84         securityContext.setAuthentication(authentication);
    85         SecurityContextHolder.setContext(securityContext);
    86         org.activiti.engine.impl.identity.Authentication.setAuthenticatedUserId(username);
    87     }
    88 }

    第四步,添加权限配置信息。

    正常项目中,权限信息存储于数据库当中。本文为了陈述方便,直接将权限信息定义在配置类当中。

    package pers.lbf.springbootactiviti.config;
    
    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;
    
    import java.util.Arrays;
    import java.util.List;
    import java.util.stream.Collectors;
    
    /**
     * @author 赖柄沣 bingfengdev@aliyun.com
     * @version 1.0
     * @date 2020/8/18 11:40
     */
    @Configuration
    public class ApplicationConfig {
    
        @Bean
        public UserDetailsService getUserDetailsService(){
    
            InMemoryUserDetailsManager userDetailsManager = new InMemoryUserDetailsManager();
    
            String[][] usersGroupsAndRoles  = {
                    {"salaboy", "password", "ROLE_ACTIVITI_USER", "GROUP_activitiTeam"},
                    {"ryandawsonuk", "password", "ROLE_ACTIVITI_USER", "GROUP_activitiTeam"},
                    {"erdemedeiros", "password", "ROLE_ACTIVITI_USER", "GROUP_activitiTeam"},
                    {"other", "password", "ROLE_ACTIVITI_USER", "GROUP_otherTeam"},
                    {"system", "password", "ROLE_ACTIVITI_USER"},
                    {"admin", "password", "ROLE_ACTIVITI_ADMIN"}
            };
    
            for (String[] user : usersGroupsAndRoles) {
                List<String> authoritiesStrings = Arrays.asList(Arrays.copyOfRange(user,2,user.length));
    
                userDetailsManager.createUser(new User(
                            user[0],
                            passwordEncoder().encode(user[1]),
                            authoritiesStrings.stream().map(SimpleGrantedAuthority::new).collect(Collectors.toList())
                        )
                );
    
            }
    
            return userDetailsManager;
        }
    
        @Bean
        public PasswordEncoder passwordEncoder() {
            return new BCryptPasswordEncoder();
        }
    }

    第五步,整合Junit,验证是否整合成功

    首先,添加Junit依赖

            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <scope>test</scope>
            </dependency>    

    编写测试类

      1 package pers.lbf.springbootactiviti.activititest;
      2 
      3 import org.activiti.api.process.model.ProcessDefinition;
      4 import org.activiti.api.process.model.builders.ProcessPayloadBuilder;
      5 import org.activiti.api.process.model.payloads.StartProcessPayload;
      6 import org.activiti.api.process.runtime.ProcessRuntime;
      7 import org.activiti.api.runtime.shared.query.Page;
      8 import org.activiti.api.runtime.shared.query.Pageable;
      9 import org.activiti.api.task.model.Task;
     10 import org.activiti.api.task.model.builders.ClaimTaskPayloadBuilder;
     11 import org.activiti.api.task.model.builders.CompleteTaskPayloadBuilder;
     12 import org.activiti.api.task.runtime.TaskRuntime;
     13 import org.activiti.engine.ProcessEngine;
     14 import org.activiti.engine.RepositoryService;
     15 import org.activiti.engine.repository.Deployment;
     16 import org.junit.Before;
     17 import org.junit.Test;
     18 import org.junit.runner.RunWith;
     19 import org.springframework.beans.factory.annotation.Autowired;
     20 import org.springframework.boot.test.context.SpringBootTest;
     21 import org.springframework.test.context.junit4.SpringRunner;
     22 import pers.lbf.springbootactiviti.utils.SecurityUtil;
     23 
     24 import java.util.List;
     25 
     26 /**
     27  * @author 赖柄沣 bingfengdev@aliyun.com
     28  * @version 1.0
     29  * @date 2020/8/18 12:10
     30  */
     31 @RunWith(SpringRunner.class)
     32 @SpringBootTest
     33 public class Activiti7SpringbootTest {
     34 
     35     @Autowired
     36     private ProcessRuntime processRuntime;
     37     @Autowired
     38     private TaskRuntime taskRuntime;
     39 
     40     @Autowired
     41     private SecurityUtil securityUtil;
     42 
     43     @Autowired
     44     private ProcessEngine processEngine;
     45 
     46     @Before
     47     public void init() {
     48         //认证
     49         securityUtil.logInAs("system");
     50     }
     51 
     52     /**部署流程
          说明:关于流程的部署,activiti7与springboot整合后,会自动部署已经创建好的流程文件(bpmn、png)
          只要将流程定义文件存放在"resources/processes/下即可"
    53 * @author 赖柄沣 bingfengdev@aliyun.com 54 * @date 2020-08-18 12:53:51 55 * @version 1.0 56 */ 57 @Test 58 public void repositoryProcess(){ 59 RepositoryService repositoryService = processEngine.getRepositoryService(); 60 Deployment deployment = repositoryService.createDeployment() 61 .addClasspathResource("holiday.bpmn") 62 .name("请假流程") 63 .deploy(); 64 System.out.println(deployment.getName()); 65 System.out.println(deployment.getDeploymentTime()); 66 } 67 68 /**分页查询系统中所有可用的流程定义 69 * @author 赖柄沣 bingfengdev@aliyun.com 70 * @date 2020-08-18 13:32:36 71 * @version 1.0 72 */ 73 @Test 74 public void findProcessList(){ 75 Page<ProcessDefinition> processDefinitionPage = processRuntime 76 .processDefinitions(Pageable.of(0, 10)); 77 List<ProcessDefinition> content = processDefinitionPage.getContent(); 78 for (ProcessDefinition processDefinition : content) { 79 System.out.println(processDefinition.getName()); 80 } 81 } 82 83 /**启动流程 84 * @author 赖柄沣 bingfengdev@aliyun.com 85 * @date 2020-08-18 13:21:12 86 * @version 1.0 87 */ 88 @Test 89 public void startProcess(){ 90 91 StartProcessPayload myProcess = ProcessPayloadBuilder 92 .start() 93 .withProcessDefinitionId("myProcess_1:1:5c5e0de3-e112-11ea-a73b-287fcf13e373") 94 .build(); 95 96 myProcess.setProcessInstanceName("张三请假"); 97 processRuntime.start(myProcess); 98 System.out.println("流程实例"+myProcess.getId()); 99 100 } 101 102 /**查询并完成任务 103 * @author 赖柄沣 bingfengdev@aliyun.com 104 * @date 2020-08-18 13:41:40 105 * @version 1.0 106 */ 107 @Test 108 public void findAndFinishTask() { 109 Page<Task> taskPage = taskRuntime.tasks(Pageable.of(0, 10)); 110 111 if (taskPage.getTotalItems()>0){ 112 113 List<Task> content = taskPage.getContent(); 114 for (Task task : content) { 115 //拾取任务 116 taskRuntime.claim(new ClaimTaskPayloadBuilder() 117 .withTaskId(task.getId()) 118 .build()); 119 //完成任务 120 taskRuntime.complete(new CompleteTaskPayloadBuilder() 121 .withTaskId(task.getId()) 122 .build()); 123 } 124 } 125 126 } 127 128 }

    End

    本文仅介绍如何将activiti7集成到springboot中.具体的activiti使用请参考其他博文。

    本文代码github地址:https://github.com/code81192/art-demo/tree/master/springboot-activiti7

  • 相关阅读:
    [LeetCode] Contains Duplicate II
    [LeetCode] House Robber II
    [LeetCode] Permutations II
    [LeetCode] Permutations
    [LeetCode] Next Permutation
    谈谈套接字
    基于Linux系统的Nagios网络管理模块的实现
    Windows/Linux下磁盘使用的图形化工具简介
    利用日志使管理Linux更轻松
    实际感受美丽的Linux(多组视频)
  • 原文地址:https://www.cnblogs.com/bingfengdev/p/13523180.html
Copyright © 2020-2023  润新知