Activiti7整合Springboot使用记录

网友投稿 298 2022-12-17

Activiti7整合Springboot使用记录

目录0.Springboot项目创建1.引入Activiti相关依赖2.启动工程并创建activiti数据库3.流程部署4.流程实例启动5.任务查询6. 完成任务7.流程结束,或流程流转过程中的历史信息查询8.其他Api测试8.1 流程定义信息查询8.2 删除流程9.demo源码下载

0.Springboot项目创建

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

1.引入Activiti相关依赖

org.activiti

activiti-spring-boot-starter

7.1.0.M6

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 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 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

shttp://pring.activiti.deployment-mode=never-fail

spring.activiti.process-definition-location-prefix=classpath:/process/

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

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

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

-Dfile.encoding=utf-8

##进行流程设计

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张表

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 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 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("===================-============http://===");

System.out.println("");

}

}

8.其他Api测试

8.1 流程定义信息查询

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

@Test

public void queryProcessDefinition(){

//得到ProcessDefinitionQuery对象

ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();

//查询出当前所有的流程定义

List 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

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:SpringSecurity实现动态url拦截(基于rbac模型)
下一篇:SpringBoot 集成 ShedLock 分布式锁的示例详解
相关文章

 发表评论

暂时没有评论,来抢沙发吧~