案例代碼:https://gitee.com/flymini/codes01/tree/master/activiti_/learn-activiti04
****
整合步驟如下:
**1. 創建一個SpringBoot項目,`pom.xml`如下**
```xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.0.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</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>
<version>5.1.49</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.18</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
```
**2. `resources/application.yml`**
```yml
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost/activiti?useUnicode=true&characterEncoding=UTF-8
username: root
password: root
activiti:
#數據庫策略
#1.flase:默認值。activiti在啟動時,對比數據庫表中保存的版本,如果沒有表或者版本不匹配,將拋出異常(生產環境常用)
#2.true:activiti會對數據庫中所有表進行更新操作。如果表不存在,則自動創建(開發時常用)
#3.create_drop:在activiti啟動時創建表,在關閉時刪除表(必須手動關閉引擎,才能刪除表)
#4.drop-create:在activiti啟動時刪除原來的舊表,然后在創建新表(不需要手動關閉引擎)
database-schema-update: true
#activiti7默認不生成歷史信息表,開啟歷史表
db-history-used: true
#記錄歷史等級 可配置的歷史級別有none, activity, audit, full
#none:不保存任何的歷史數據,因此,在流程執行過程中,這是最高效的。
#activity:級別高于none,保存流程實例與流程行為,其他數據不保存。
#audit:除activity級別會保存的數據外,還會保存全部的流程任務及其屬性。audit為history的默認值。
#full:保存歷史數據的最高級別,除了會保存audit級別的數據外,還會保存其他全部流程相關的細節數據,包括一些流程參數等。
history-level: full
```
**3. 添加SpringSecurity安全框架整合配置**
因為Activiti7與SpringBoot整合后,默認情況下,集成了SpringSecurity安全框架,這樣我們就要去準備SpringSecurity整合進來的相關用戶權限配置信息。
(1)*`learn.activiti04.utils.SecurityUtil`*
```java
/**
* 為了能夠快速實現SpringSecurity安全框架的配置,所添加的一個組件。
* 這個類可以從我們下載的Activiti7官方提供的Example中找到。
*/
@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() {
@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);
}
}
```
(2)*`learn.activiti04.config.CustomConfig`*
```java
/**
* 設置用戶和角色
* 1)在Activiti7官方下載的Example中找到DemoApplicationConfig類,
* 它的作用是為了實現SpringSecurity框架的用戶權限的配置,這樣我們就可以在系統中使用用戶權限信息。
* 2)本次項目中基本是在文件中定義出來的用戶信息,當然也可以是數據庫中查詢的用戶權限信息。
* 3)后面處理流程時用到的任務負責人,需要添加在這里。
*/
@Slf4j
@Configuration
public class CustomConfig {
/**
* 添加Security的用戶
*/
@Bean
public UserDetailsService myUserDetailsService() {
//把用戶存儲在內存中
InMemoryUserDetailsManager inMemoryUserDetailsManager = new InMemoryUserDetailsManager();
//構造用戶的信息
String[][] usersGroupAndRoles = {
{"jack", "password", "ROLE_ACTIVITI_USER", "GROUP_activitiTeam"},
{"rose", "password", "ROLE_ACTIVITI_USER", "GROUP_activitiTeam"},
{"tom", "password", "ROLE_ACTIVITI_USER", "GROUP_activitiTeam"},
{"jerry", "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[] users : usersGroupAndRoles) {
//用戶的角色和組
List<String> authStrList = Arrays.asList(Arrays.copyOfRange(users, 2, users.length));
log.info("> Registering new user: {} with the following Authorities[{}]", users[0], authStrList);
inMemoryUserDetailsManager.createUser(new User(users[0],
passwordEncoder().encode(users[1]),
authStrList.stream().map(str -> new SimpleGrantedAuthority(str)).collect(Collectors.toList())));
}
return inMemoryUserDetailsManager;
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
```
**4. 創建Bpmn文件**
Activiti7可以自動部署流程,前提是在resources目錄下,創建一個新的目錄processes,用來放置bpmn文件。
<br/>
創建一個簡單的Bpmn流程文件,并設置任務的用戶組Candidate Groups。Candidate Groups中的內容與上面DemoApplicationConfiguration類中出現的用戶組名稱要保持一致,可以填寫:`activitiTeam` 或者 `otherTeam`。
這樣填寫的好處:當不確定到底由誰來負責當前任務的時候,只要是Groups內的用戶都可以拾取這個任務。

**5. 測試代碼**
```java
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class TestActSpringBoot {
@Autowired
private ProcessRuntime processRuntime;
@Autowired
private TaskRuntime taskRuntime;
@Autowired
private SecurityUtil securityUtil;
/**
* 查看流程定義內容
* Activiti7可以自動部署流程
*/
@Test
public void findProcess() {
//設置登錄用戶
securityUtil.logInAs("jack");
//流程定義的分頁對象
Page<ProcessDefinition> definitionPage = processRuntime.processDefinitions(Pageable.of(0, 10));
System.out.println("可用的流程定義總數:" + definitionPage.getTotalItems()); //1
for (ProcessDefinition processDefinition : definitionPage.getContent()) {
//ProcessDefinition{id='mydemo:1:ccad0c95-2a61-11ec-b839-5492dfcbba11', name='null', key='mydemo',...
System.out.println("流程定義內容:" + processDefinition);
System.out.println();
}
}
/**
* 啟動流程
*/
@Test
public void startProcess() {
//設置登錄用戶
securityUtil.logInAs("system");
ProcessInstance processInstance = processRuntime.
start(ProcessPayloadBuilder
.start()
.withProcessDefinitionKey("mydemo") //流程定義key
.build());
log.info("流程實例的內容,{}", processInstance);
}
/**
* 執行任務
*/
@Test
public void doTask() {
//設置登錄用戶
securityUtil.logInAs("jerry");
//查詢任務
Page<Task> taskPage = taskRuntime.tasks(Pageable.of(0, 10));
if (taskPage != null && taskPage.getTotalItems() > 0) {
for (Task task : taskPage.getContent()) {
//拾取任務
taskRuntime.claim(TaskPayloadBuilder
.claim()
.withTaskId(task.getId())
.build());
log.info("任務內容,{}", task);
//完成任務
taskRuntime.complete(TaskPayloadBuilder
.complete()
.withTaskId(task.getId())
.build());
}
}
}
}
```
- Activiti流程引擎
- 工作流介紹
- Activiti是什么
- Activiti流程處理步驟
- Activiti環境搭建
- 搭建步驟
- 表結構介紹
- ActivitiAPI結構
- 認識流程符號
- 流程設計器的使用
- 流程處理步驟
- 亂碼問題
- 流程實例
- 流程實例是什么
- 業務標識
- 查詢流程實例
- 掛起/激活流程實例
- 個人任務
- 分配任務負責人
- 查詢待辦任務
- 辦理權限
- 流程變量
- 流程變量類型
- 流程變量作用域
- 使用流程變量控制流程
- 組任務
- 設置任務候選人
- 組任務辦理流程
- 網關
- 4種網關類型
- 排他網關
- 并行網關
- 包含網關
- 事件網關
- Spring整合Activiti
- SpringBoot整合Activiti
- Flowable流程引擎
- Flowable是什么
- Flowable與Activiti
- Flowable環境搭建
- FlowableAPI
- 流程引擎API與服務
- 流程處理步驟
- 流程部署
- 流程部署方式
- 流程定義版本
- 刪除已部署的流程
- 下載資源
- 流程實例
- 什么是流程實例
- 業務標識
- 查詢流程實例
- 掛起/激活流程實例
- 分配任務負責人
- 固定分配
- UEL表達式分配
- 監聽器分配
- 辦理權限
- 流程變量
- 流程變量類型
- 流程變量作用域
- 流程變量控制流程
- 組任務
- 設置任務候選人
- 組任務辦理流程
- 網關
- 排他網關
- 并行網關
- 包含網關
- 事件網關
- 歷史查詢
- 查詢歷史
- Spring整合Flowable
- 配置文件整合
- 配置類整合
- SpringBoot整合Flowable