Activiti7整合Springboot使用記錄
0.Springboot項(xiàng)目創(chuàng)建
通過(guò)https://start.spring.io/生成純凈的一個(gè)springboot工程
1.引入Activiti相關(guān)依賴
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter</artifactId>
<version>7.1.0.M6</version>
</dependency>
2.啟動(dòng)工程并創(chuàng)建activiti數(shù)據(jù)庫(kù)
##activiti7中使用spring security,因此啟動(dòng)工程前,需要加入2個(gè)文件支持,2個(gè)文件的代碼如下:
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/
##啟動(dòng)springboot工程,讓系統(tǒng)啟動(dòng)時(shí)幫我們建好25張表 2.安裝Activiti插件(設(shè)計(jì)器) ##Idea
file->settings->plugins,然后找actiBPM進(jìn)行安裝。
##流程圖中亂碼問(wèn)題先提前設(shè)置防止:
修改idea64.exe.vmoptions文件,在文件中加上如下,然后重啟Idea
-Dfile.encoding=utf-8
##進(jìn)行流程設(shè)計(jì)
File->new->BpmnFile
設(shè)計(jì)好后,修改Process1.bpmn成Process1.xml,然后右鍵export file導(dǎo)出成Process1.jpg,再將Process1.bpmn修改成Process1.bpmn20.xml,最后將2個(gè)文件放在process文件夾

3.流程部署
使用activiti提供的api把流程定義內(nèi)容存儲(chǔ)起來(lái),Activiti執(zhí)行把流程定義內(nèi)容存儲(chǔ)在數(shù)據(jù)庫(kù)中。
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實(shí)例
@Autowired
private RepositoryService repositoryService;
//0.流程部署,單個(gè)文件部署方式
@Test
public void testDeployment(){
//使用RepositoryService進(jìn)行部署
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
}
}
執(zhí)行此操作后activiti會(huì)將上邊代碼中指定的bpmn20文件和圖片文件保存在activiti數(shù)據(jù)庫(kù)。
流程定義部署后操作activiti的3張表



4.流程實(shí)例啟動(dòng)
啟動(dòng)一個(gè)流程實(shí)例表示開(kāi)始一次業(yè)務(wù)流程的運(yùn)行
//1.流程實(shí)例啟動(dòng)
@Test
public void testStartProcess(){
//根據(jù)流程定義Id啟動(dòng)流程
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("myProcess_1");
//輸出實(shí)例信息
System.out.println("流程定義id:" + processInstance.getProcessDefinitionId());
System.out.println("流程實(shí)例id:" + processInstance.getId());
System.out.println("當(dāng)前活動(dòng)Id:" + processInstance.getActivityId());
//流程定義id:myProcess_1:1:12702ed4-ffd9-11eb-8847-02004c4f4f50
//流程實(shí)例id:a9b162aa-ffda-11eb-bad1-02004c4f4f50
//當(dāng)前活動(dòng)Id:null
}
流程實(shí)例啟動(dòng),將操作以下幾個(gè)數(shù)據(jù)庫(kù)表
act_hi_actinst 流程實(shí)例執(zhí)行歷史 act_hi_identitylink 流程的參與用戶歷史信息 act_hi_procinst 流程實(shí)例歷史信息 act_hi_taskinst 流程任務(wù)歷史信息 act_ru_execution 流程執(zhí)行信息 act_ru_identitylink 流程的參與用戶信息 act_ru_task 任務(wù)信息
5.任務(wù)查詢
流程啟動(dòng)后,任務(wù)的負(fù)責(zé)人就可以查詢自己當(dāng)前需要處理的任務(wù),查詢出來(lái)的任務(wù)都是該用戶的待辦任務(wù)。
//2.任務(wù)查詢
//流程啟動(dòng)后,任務(wù)的負(fù)責(zé)人就可以查詢自己當(dāng)前需要處理的任務(wù),查詢出來(lái)的任務(wù)都是該用戶的待辦任務(wù)。
@Test
public void testFindPersonalTaskList() {
//任務(wù)負(fù)責(zé)人
String assignee = "liuky";
//根據(jù)流程key 和 任務(wù)負(fù)責(zé)人 查詢?nèi)蝿?wù)
List<Task> list = taskService.createTaskQuery()
.processDefinitionKey("myProcess_1")
.taskAssignee(assignee)
.list();
for (Task task : list) {
System.out.println("流程實(shí)例id:" + task.getProcessInstanceId());
System.out.println("任務(wù)id:" + task.getId());
System.out.println("任務(wù)負(fù)責(zé)人:" + task.getAssignee());
System.out.println("任務(wù)名稱:" + task.getName());
}
//流程實(shí)例id:a9b162aa-ffda-11eb-bad1-02004c4f4f50
//任務(wù)id:a9b5815e-ffda-11eb-bad1-02004c4f4f50
//任務(wù)負(fù)責(zé)人:liuky
//任務(wù)名稱:提交申請(qǐng)
}
6. 完成任務(wù)
@Test
public void completTask(){
//根據(jù)流程key和任務(wù)的負(fù)責(zé)人查詢?nèi)蝿?wù)并選擇其中的一個(gè)任務(wù)處理,這里用的
//是singleResult返回一條,真實(shí)環(huán)境中是通過(guò)步驟5中查詢出所有的任務(wù),然后在頁(yè)面上選擇一個(gè)任務(wù)進(jìn)行處理.
Task task = taskService.createTaskQuery()
.processDefinitionKey("myProcess_1") //流程Key
.taskAssignee("liuky") //要查詢的負(fù)責(zé)人
.singleResult();
//完成任務(wù),參數(shù):任務(wù)id
taskService.complete(task.getId());
}
7.流程結(jié)束,或流程流轉(zhuǎn)過(guò)程中的歷史信息查詢
//流程結(jié)束,或流程流轉(zhuǎn)過(guò)程中的歷史信息查詢
@Test
public void findHistoryInfo(){
//獲取 actinst表的查詢對(duì)象
HistoricActivityInstanceQuery instanceQuery = historyService.createHistoricActivityInstanceQuery();
//查詢 actinst表,條件:根據(jù) InstanceId 查詢
instanceQuery.processInstanceId("fb5b7674-ffde-11eb-91f8-02004c4f4f50");
//增加排序操作,orderByHistoricActivityInstanceStartTime 根據(jù)開(kāi)始時(shí)間排序 asc 升序
instanceQuery.orderByHistoricActivityInstanceStartTime().asc();
//查詢所有內(nèi)容
List<HistoricActivityInstance> activityInstanceList = instanceQuery.list();
//輸出結(jié)果
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測(cè)試
8.1 流程定義信息查詢
查詢流程相關(guān)信息,包含流程定義,流程部署,流程定義版本
@Test
public void queryProcessDefinition(){
//得到ProcessDefinitionQuery對(duì)象
ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
//查詢出當(dāng)前所有的流程定義
List<ProcessDefinition> definitionList = processDefinitionQuery.processDefinitionKey("myProcess_1")
.orderByProcessDefinitionVersion()
.desc()
.list();
//打印結(jié)果
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";
//刪除流程定義,如果該流程定義已有流程實(shí)例啟動(dòng)則刪除時(shí)出錯(cuò)
repositoryService.deleteDeployment(deploymentId);
//設(shè)置true 級(jí)聯(lián)刪除流程定義,即使該流程有流程實(shí)例啟動(dòng)也可以刪除,設(shè)置為false非級(jí)別刪除方式,如果流程
//repositoryService.deleteDeployment(deploymentId, true);
}
9.demo源碼下載
github: https://github.com/jxlhljh/activitidemotest.git
gitee: https://gitee.com/jxlhljh/activitidemotest.git
到此這篇關(guān)于Activiti7整合Springboot使用記錄的文章就介紹到這了,更多相關(guān)Springboot整合Activiti7內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot實(shí)用小技巧之如何動(dòng)態(tài)設(shè)置日志級(jí)別
這篇文章主要給大家介紹了關(guān)于SpringBoot實(shí)用小技巧之如何動(dòng)態(tài)設(shè)置日志級(jí)別的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用SpringBoot具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04
springboot如何為web層添加統(tǒng)一請(qǐng)求前綴
這篇文章主要介紹了springboot如何為web層添加統(tǒng)一請(qǐng)求前綴,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02
Java使用JSONObject需要的6個(gè)jar包下載地址
這篇文章主要介紹了Java使用JSONObject需要的6個(gè)jar包下載地址,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11
解讀SpringBoot中addCorsMappings配置跨域與攔截器互斥問(wèn)題的原因
這篇文章主要介紹了解讀SpringBoot中addCorsMappings配置跨域與攔截器互斥問(wèn)題的原因,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12
Spring Boot設(shè)置支持跨域請(qǐng)求過(guò)程詳解
這篇文章主要介紹了Spring Boot設(shè)置支持跨域請(qǐng)求過(guò)程詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08
java 中Executor, ExecutorService 和 Executors 間的不同
這篇文章主要介紹了java 中Executor, ExecutorService 和 Executors 間的不同的相關(guān)資料,需要的朋友可以參考下2017-06-06
Java 數(shù)據(jù)庫(kù)連接(JDBC)的相關(guān)總結(jié)
這篇文章主要介紹了Java 數(shù)據(jù)庫(kù)連接(JDBC)的相關(guān)總結(jié),幫助大家更好的理解和學(xué)習(xí)使用Java,感興趣的朋友可以了解下2021-03-03
Java提示解析時(shí)已到達(dá)文件結(jié)尾的解決方法
在本篇文章中小編給大家分享了關(guān)于Java提示解析時(shí)已到達(dá)文件結(jié)尾的解決方法,需要的朋友們學(xué)習(xí)下。2019-07-07




