• 【activiti】activiti与springboot整合


    activiti与springboot整合

    创建工程

    1、pom

    <parent>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-parentartifactId>
        <version>2.1.0.RELEASEversion>
    parent>
    <properties>
        <project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
        <java.version>1.8java.version>
    properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-webartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-jdbcartifactId>
        dependency>
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-testartifactId>
        dependency>
        <dependency>
            <groupId>org.activitigroupId>
            <artifactId>activiti-spring-boot-starterartifactId>
            <version>7.0.0.Beta2version>
        dependency>
        <dependency>
            <groupId>mysqlgroupId>
            <artifactId>mysql-connector-javaartifactId>
            <version>5.1.29version>
        dependency>
        <dependency>
            <groupId>org.projectlombokgroupId>
            <artifactId>lombokartifactId>
        dependency>
    dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.bootgroupId>
                <artifactId>spring-boot-maven-pluginartifactId>
            plugin>
        plugins>
    build>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46

    2、application.yml

    spring:
      datasource:
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://localhost:3306/activiti?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai
        username: root
        password: root
      activiti:
    #    false:默认值。在activiti启动时,会对比数据库表中保存的版本,如果没有表或版本不匹配,将抛出异常。(生产环境常用)
    #    true:activiti会对数据库中所有表进行更新操作。如果表不存在,将会创建。(开发环境常用)
    #    create-drop:在activiti启动时创建表,在关闭时删除表,必须手动关闭引擎才会删除表。(单元测试用)
    #    drop-create:在activiti启动时删除旧表,然后创建新表,不需要关闭引擎。
        database-schema-update: true
        #检测历史表是否存在,activiti7默认没有开启数据库历史记录,true启动数据库历史记录
        db-history-used: true
        #记录历史等级,可配置的历史级别有:none,activity,audit,full
        # none:不保存任何的历史数据,因此在流程执行过程中,这是最高效的
        # activity:级别高于none,保存流程实例与流程行为,其他数据不保存
        # audit:除保存activity保存的数据外,还会保存全部的流程任务及其属性。history-level的默认值
        # full:保存历史数据的最高级别,会额外保存全部流程相关的细节数据。
        history-level: full
        #校验流程文件,默认校验resources下的process文件夹的流程文件
        check-process-definitions: false
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    3、启动类

    @SpringBootApplication
    public class ActivitiApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(ActivitiApplication.class, args);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    4、经典类测试

    同之前一样,配置完成后,创建相应的Service服务即可进行操作

    @RunWith(SpringRunner.class)
    @SpringBootTest(classes = ActivitiApplication.class)
    public class Test01 {
    
        @Autowired
        private RepositoryService repositoryService;
    
        @Autowired
        private RuntimeService runtimeService;
    
        @Test
        public void deployment() {
            repositoryService.createDeployment()
                    .name("activiti-springboot")
                    .addClasspathResource("bpmn/activiti-springboot.bpmn20.xml")
                    .deploy();
        }
    
        @Test
        public void startProcess() {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("assignee0", "zhangsan");
            ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("activiti-springboot", map);
            System.out.println(processInstance.getProcessDefinitionKey());
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    5、新特性测试

    在activiti7的新特性:

    1. 更好的支持springboot
    2. 引入springsecurity安全机制
    3. 核心API进行了封装
    4. 对云发布、分布式支持等
    5.1、添加springsecurity配置

    activiti7与springboot整合后,默认情况下就集成了springsecurity,所以我们需要准备springsecurity的相关配置。

    不然会提示异常。

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lHsy1Lmc-1658298356742)(https://cdn.jsdelivr.net/gh/le1024/image1/le/image-20211223152441669.png)]

    SecurityUtil

    @Slf4j
    @Component
    public class SecurityUtil {
    
        @Autowired
        private UserDetailsService userDetailsService;
    
        /**
         * 模拟用户登录
         * @param username 用户名
         */
        public void login(String username) {
            UserDetails user = userDetailsService.loadUserByUsername(username);
            if (user == null) {
                throw new IllegalArgumentException("user doesn`t exist");
            }
            log.info("login :" + username);
    
            SecurityContextHolder.setContext(new SecurityContextImpl(new Authentication() {
                private static final long serialVersionUID = 3397680986162930722L;
    
                public Collection<? extends GrantedAuthority> getAuthorities() {
                    return user.getAuthorities();
                }
    
                public Object getCredentials() {
                    return user.getPassword();
                }
    
                public Object getDetails() {
                    return user;
                }
    
                public Object getPrincipal() {
                    return user;
                }
    
                public boolean isAuthenticated() {
                    return true;
                }
    
                public void setAuthenticated(boolean b) throws IllegalArgumentException {
    
                }
    
                public String getName() {
                    return user.getUsername();
                }
            }));
    
            org.activiti.engine.impl.identity.Authentication.setAuthenticatedUserId(username);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54

    SecurityConfig

    @Slf4j
    @Configuration
    public class SecurityConfig {
    
        @Bean
        public UserDetailsService userDetailsService() {
            InMemoryUserDetailsManager inMemoryUserDetailsManager = new InMemoryUserDetailsManager();
            //添加用户
            String[][] userGroupsAndRoles = {
                    {"jack", "password", "ROLE_ACTIVITI_USER", "GROUP_activitiTeam"},
                    {"rose", "password", "ROLE_ACTIVITI_USER", "GROUP_activitiTeam"},
                    {"tom", "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 : userGroupsAndRoles) {
                List<String> authorities = Arrays.asList(Arrays.copyOfRange(user, 2, user.length));
                log.info("注册新用户:{},用户权限:{}", user[0], authorities);
                inMemoryUserDetailsManager.createUser(
                        new User(
                                user[0],
                                passwordEncoder().encode(user[1]),
                                authorities.stream().map(SimpleGrantedAuthority::new).collect(Collectors.toList())
                        )
                );
            }
            return inMemoryUserDetailsManager;
        }
    
        @Bean
        public PasswordEncoder passwordEncoder() {
            return new BCryptPasswordEncoder();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    5.2、创建bpmn文件

    根据自己的需要设计,学习教程中如下:

    image-20211223172852356

    5.3、测试类
    /*
         * 直接引入activiti7新增的api,通过新的api操作
         */
        @Autowired
        private ProcessRuntime processRuntime;
        @Autowired
        private TaskRuntime taskRuntime;
        @Autowired
        private SecurityUtil securityUtil;
    
        @Autowired
        private RepositoryService repositoryService;
    
        /**
         * 部署流程
         */
        @Test
        public void deployment() {
            repositoryService.createDeployment()
                    .name("activiti-springboot")
                    .addClasspathResource("bpmn/activiti-springboot.bpmn20.xml")
                    .deploy();
        }
    
        /**
         * 查看流程定义
         */
        @Test
        public void viewProcessDefinition() {
            //需要模拟登录一个用户,不然会报异常
            securityUtil.login("system");
            Page<ProcessDefinition> definitionPage = processRuntime.processDefinitions(Pageable.of(0, 10));
            System.out.println("可用的流程定数数量:" + definitionPage.getTotalItems());
    
            for (ProcessDefinition definition : definitionPage.getContent()) {
                System.out.println("流程定义id:" + definition.getId());
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    启动流程实例

    /**
         * 启动流程实例
         */
        @Test
        public void startProcess() {
            //需要模拟登录一个用户
            securityUtil.login("system");
    
            //设置变量
            Map<String, Object> map = new HashMap<>();
            map.put("assignee0", "jack");
    
            ProcessInstance instance = processRuntime.start(ProcessPayloadBuilder
                    .start()
                    .withProcessDefinitionKey("activiti-springboot")
                    .withVariables(map)
                    .build());
    
            System.out.println("流程实例id:" + instance.getId());
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    查询个人任务

    /**
         * 查询个人任务
         */
        @Test
        public void queryTask() {
            //执行完流程实例后分配的任务是给jack了,现在用jack登录
            securityUtil.login("jack");
    
            Page<Task> taskPage = taskRuntime.tasks(Pageable.of(0, 10));
    
            for (Task task : taskPage.getContent()) {
                System.out.println("任务id:" + task.getId());
                System.out.println("任务name:" + task.getName());
            }
    
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    完成个人任务

    /**
         * 完成个人任务
         */
        @Test
        public void completeTask() {
            //执行完流程实例后分配的任务是给jack了,现在用jack登录
            securityUtil.login("jack");
            Page<Task> taskPage = taskRuntime.tasks(Pageable.of(0, 10));
    
            for (Task task : taskPage.getContent()) {
                //完成任务
                taskRuntime.complete(TaskPayloadBuilder
                        .complete()
                        .withTaskId(task.getId())
                        .build());
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    拾取任务

    需要创建一份新的流程,实现组任务,不然拾取不了

    /**
         * 拾取任务
         * 登录人必须是任务的候选人才可以,自行配置好测试
         */
        @Test
        public void claimTask() {
            securityUtil.login("rose");
    
            taskRuntime.claim(TaskPayloadBuilder
                    .claim()
                    //任务id应该是查询出来的,这里直接从数据库复制了
                    .withTaskId("f2ca7116-63d5-11ec-b2e7-005056c00008")
                    .build());
            System.out.println("拾取任务成功");
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
  • 相关阅读:
    汉语史稿重点
    Unity Render Streaming通过Js与Unity自定义通讯
    java毕业设计共享单车系统mybatis+源码+调试部署+系统+数据库+lw
    Jmeter引入外部jar包以满足加密数据的Post请求
    Spring Cloud 学习笔记(2 3)
    mac 安装 selenium + chrome driver
    Python连接MYSQL、SQL Server、Oracle数据入库一网打尽
    实现基于 GitLab 的数据库 CI/CD 最佳实践
    电源模块测试用例科普:如何调整电压调整率?ATECLOUD-POWER测试系统能否测试?
    谷歌翻译下载-大家都在用的批量谷歌翻译软件下载
  • 原文地址:https://blog.csdn.net/sinat_33151213/article/details/125891599