Activiti7发布正式版本之后,它和SpringBoot2.x已经完全整合开发了

1.1 添加相关的依赖

        <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><exclusions><exclusion><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.activiti</groupId><artifactId>activiti-spring-boot-starter</artifactId><version>7.0.0.Beta2</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency>

1.2 修改配置文件

# 配置Spring的数据源
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql:///activiti?characterEncoding=utf-8&amp;nullCatalogMeansCurrent=true&amp;serverTimezone=UTC
spring.datasource.name=root
spring.datasource.password=123456# activiti的配置
#1.flase:默认值。activiti在启动时,对比数据库表中保存的版本,如果没有表或者版本不匹配,将抛出异常
#2.true: activiti会对数据库中所有表进行更新操作。如果表不存在,则自动创建
#3.create_drop: 在activiti启动时创建表,在关闭时删除表(必须手动关闭引擎,才能删除表)
#4.drop-create: 在activiti启动时删除原来的旧表,然后在创建新表(不需要手动关闭引擎)
spring.activiti.database-schema-update=true
# 检测历史表是否存在, Activiti7中默认是没有开启数据库历史记录的,启动数据库历史记录
spring.activiti.db-history-used=true
#记录历史等级 可配置的历史级别有none, activity, audit, full
#none:不保存任何的历史数据,因此,在流程执行过程中,这是最高效的。
#activity:级别高于none,保存流程实例与流程行为,其他数据不保存。
#audit:除activity级别会保存的数据外,还会保存全部的流程任务及其属性。audit为history的默认值。
#full:保存历史数据的最高级别,除了会保存audit级别的数据外,还会保存其他全部流程相关的细节数据,包括一些流程参数等。
spring.activiti.history-level=full
# 校验流程文件,默认校验resouces下的 process 文件夹里的流程文件
spring.activiti.check-process-definitions=false

1.3 整合SpringSecurity

因为Activiti7和SpringBoot整合后,默认情况下,集成了SpringSecurity安全框架,这样我们就要准备SpringSecurity的相关配置信息

添加一个SpringSecurity的工具类

package com.lujunfeng.utils;import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.ComponentScan;
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 java.util.Collection;@Component
public class SecurityUtil {private Logger logger = LoggerFactory.getLogger(SecurityUtil.class);@Autowired@Qualifier("myUserDetailsService")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");}logger.info("> Logged in as: " + username);SecurityContextHolder.setContext(new SecurityContextImpl(new Authentication() {@Overridepublic Collection<? extends GrantedAuthority> getAuthorities() {return user.getAuthorities();}@Overridepublic Object getCredentials() {return user.getPassword();}@Overridepublic Object getDetails() {return user;}@Overridepublic Object getPrincipal() {return user;}@Overridepublic boolean isAuthenticated() {return true;}@Overridepublic void setAuthenticated(boolean isAuthenticated) throws IllegalArgumentException {}@Overridepublic String getName() {return user.getUsername();}}));org.activiti.engine.impl.identity.Authentication.setAuthenticatedUserId(username);}
}

这个类可以从Activiti7官方提供的Example中找到。

添加一个SpringSecurity的配置文件

package com.lujunfeng.config;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;import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
@Configuration
public class SpringSecurityConfiguration {private Logger logger = LoggerFactory.getLogger(SpringSecurityConfiguration.class);@Beanpublic UserDetailsService myUserDetailsService() {InMemoryUserDetailsManager inMemoryUserDetailsManager = new InMemoryUserDetailsManager();//这里添加用户,后面处理流程时用到的任务负责人,需要添加在这里String[][] usersGroupsAndRoles = {{"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 : 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;}@Beanpublic PasswordEncoder passwordEncoder() {return new BCryptPasswordEncoder();}
}

2.4 创建bpmn文件

创建一个简单的bpmn文件,并设置任务的用户组,CandidateGroups,CandidateGroups中的内容要与在SpringSecurity的配置文件中配置的用户组的名称要保持一致,可以填写activitTeam或者otherTeam。这样填写的好处是,当不确定到底由谁来负责当前的任务的时候,只要是Groups内的用户都可以拾取这个任务

Activiti7中可以自动部署流程,前提是在resources目录下,创建一个新的目录processes,用来放置bpmn文件

1.5 单元测试

package com.lujunfeng;import com.lujunfeng.utils.SecurityUtil;
import org.activiti.api.process.model.ProcessDefinition;
import org.activiti.api.process.model.ProcessInstance;
import org.activiti.api.process.model.builders.ProcessPayloadBuilder;
import org.activiti.api.process.runtime.ProcessRuntime;
import org.activiti.api.runtime.shared.query.Page;
import org.activiti.api.runtime.shared.query.Pageable;
import org.activiti.api.task.model.Task;
import org.activiti.api.task.model.builders.ClaimTaskPayloadBuilder;
import org.activiti.api.task.model.builders.TaskPayloadBuilder;
import org.activiti.api.task.model.payloads.ClaimTaskPayload;
import org.activiti.api.task.runtime.TaskRuntime;
import org.activiti.engine.RepositoryService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;@SpringBootTest
class ActSpringbootApplicationTests {@Autowiredprivate ProcessRuntime processRuntime;@Autowiredprivate TaskRuntime taskRuntime;@Autowiredprivate SecurityUtil securityUtil;@Autowiredprivate RepositoryService repositoryService;@Testvoid contextLoads() {System.out.println(taskRuntime);}/*** 查询流程的定义*/@Testpublic void test02(){securityUtil.logInAs("system");Page<ProcessDefinition> processDefinitionPage =processRuntime.processDefinitions(Pageable.of(0, 10));System.out.println("可用的流程定义数量:" + processDefinitionPage.getTotalItems());for (ProcessDefinition processDefinition : processDefinitionPage.getContent()) {System.out.println("流程定义:" + processDefinition);}}/*** 部署流程*/@Testpublic void test03(){repositoryService.createDeployment().addClasspathResource("processes/my-evection.bpmn").addClasspathResource("processes/my-evection.png").name("出差申请单").deploy();}/*** 启动流程实例*/@Testpublic void test04(){securityUtil.logInAs("system");ProcessInstance processInstance = processRuntime.start(ProcessPayloadBuilder.start().withProcessDefinitionKey("my-evection").build());System.out.println("流程实例id:" + processInstance.getId());}/*** 任务查询、拾取及完成操作*/@Testpublic void test05(){securityUtil.logInAs("jack");Page<Task> tasks = taskRuntime.tasks(Pageable.of(0, 10));if(tasks != null && tasks.getTotalItems() > 0){for (Task task : tasks.getContent()) {// 拾取任务taskRuntime.claim(TaskPayloadBuilder.claim().withTaskId(task.getId()).build());System.out.println("任务:" + task);taskRuntime.complete(TaskPayloadBuilder.complete().withTaskId(task.getId()).build());}}Page<Task> taskPage2 = taskRuntime.tasks(Pageable.of(0,10));if(taskPage2 .getTotalItems() > 0){System.out.println("任务:" + taskPage2.getContent());}}}

activiti7和SpringBoot的整合相关推荐

  1. 解决:Activiti7与SpringBoot整合时,默认生成的activiti数据库中只有17张表,无另外8张历史表

    问题 Activiti7与SpringBoot整合时,默认生成的activiti数据库中只有17张表,无另外8张历史表. 原因 Activiti默认关闭了历史表的使用. 解决 在连接数据库的appli ...

  2. Activiti与SpringBoot的整合

    1.pom依赖 <!--activiti7与SpringBoot整合的相关依赖--><parent><groupId>org.springframework.boo ...

  3. Docker 部署 SpringBoot 项目整合 Redis 镜像做访问计数Demo

    Docker 部署SpringBoot项目整合 Redis 镜像做访问计数Demo 最终效果如下 大概就几个步骤 1.安装 Docker CE 2.运行 Redis 镜像 3.Java 环境准备 4. ...

  4. springboot+security整合(1)

    说明 springboot 版本 2.0.3 源码地址:点击跳转 系列 springboot+security 整合(1) springboot+security 整合(2) springboot+s ...

  5. SpringBoot服务整合(整合邮件服务、定时调度、Actuator监控)

    在进行项目开发的时候经常会遇见以下的几个问题:需要进行邮件发送.定时的任务调度.系统的监控处理,实际上这些操 作都可以通过 SpringBoot 进行整合操作.2.1.SpringBoot 整合邮件服 ...

  6. springboot下整合各种配置文件

    本博是在springboot下整合其他中间件,比如,mq,redis,durid,日志...等等  以后遇到再更.springboot真是太便捷了,让我们赶紧涌入到springboot的怀抱吧. ap ...

  7. springboot项目整合mybatis

    SpringBoot项目整合mybatis 本章内容 使用 idea创建 SpringBoot项目 SpringBoot项目中配制 mybatis 框架 1 创建 SpringBoot项目 1.1 在 ...

  8. SpringBoot系列九:SpringBoot服务整合(整合邮件服务、定时调度、Actuator监控)

    声明:本文来源于MLDN培训视频的课堂笔记,写在这里只是为了方便查阅. 1.概念:SpringBoot 服务整合 2.背景 在进行项目开发的时候经常会遇见以下的几个问题:需要进行邮件发送.定时的任务调 ...

  9. SpringBoot项目整合Retrofit最佳实践,这才是最优雅的HTTP客户端工具!

    作者:六点半起床 juejin.im/post/6854573211426750472 大家都知道okhttp是一款由square公司开源的java版本http客户端工具.实际上,square公司还开 ...

最新文章

  1. SQL Server 中WITH (NOLOCK)浅析
  2. Visual C++ 2008入门经典 第十五章 在窗口中绘图
  3. IIS发布ASP.NET应用常见错误及解决办法
  4. mybaits十八:内置标签
  5. ABAP web service运行时的细节调试
  6. 如果华为自主的操作系统,对消费者和华为会有什么影响?
  7. Android之解决java.lang.NoSuchMethodError:android.os.powerManager.isInteractive问题
  8. LeetCode LCS 03. 主题空间(广度优先搜索BFS)
  9. 这些有笑点的故事,只有程序员才能get
  10. Spoken English-口语-练习频次
  11. 浅谈DOMContentLoaded事件及其封装方法
  12. s2结业项目营业网点查询_论文发表完成科研项目的材料
  13. oeasy教您玩转vim - 005 - # 程序本质
  14. zic - 时区编辑器
  15. 【AI视野·今日NLP 自然语言处理论文速览 第三期】Tue, 8 Jun 2021
  16. C++ 中的指针参数传递和引⽤参数传递
  17. 【sy3_类组合的应用与编程_3_Whole】
  18. [今日说法]联系方式
  19. AI英雄 | 八问机器学习泰斗Jordan教授:AI其实并不神奇
  20. SAP-采购到应付过程中的会计分录

热门文章

  1. 理解 decltype关键字
  2. Win7与Ubuntu双系统下 卸载Ubuntu
  3. 京津冀凝聚力尚欠火候
  4. [转载]使用正则表达式验证本地化数据
  5. 变频器MATLAB仿真模型(前端采用二极管整流,含有进线电抗器,预充电模块,母校电容与均压电阻
  6. 微软官方Win8.1预览版下载大全(含简体中文)
  7. 面向对象的 JavaScript:封装、继承与多态
  8. 文件大小与占用空间大小不同的原因
  9. SWOOLE高性能内存数据库的使用和配置教程
  10. PrepareStatement用法(附源码解析)