本文介绍如何将 Activiti 整合到 Spring Boot。
Spring Boot
先创建一个基本的能使用数据库的 Spring Boot 应用。
添加依赖:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>9.3.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
除了基本的 Spring Boot 的 starter 以外,这里还使用了 Spring Boot 的 jdbc 的 Starter,以及 Mysql 驱动依赖。
配置文件中添加数据库连接配置:
spring
application
name demo
datasource
driver-class-name com.mysql.cj.jdbc.Driver
url jdbc mysql //localhost 3306/activiti2
username root
password mysql
创建数据库,并且添加一个用于测试的表:
CREATE TABLE `users` (
`id` bigint unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(45) COLLATE utf8mb4_general_ci DEFAULT NULL,
`age` tinyint DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
写入一些测试数据用于测试。
编写一个简单测试用例测试数据库连接没有问题:
class DemoApplicationTests {
private DataSource dataSource;
void contextLoads() throws SQLException {
Connection connection = dataSource.getConnection();
Statement statement = connection.createStatement();
String sql = "select * from users";
ResultSet resultSet = statement.executeQuery(sql);
while (resultSet.next()){
int id = resultSet.getInt("id");
String name = resultSet.getString("name");
int age = resultSet.getInt("age");
System.out.println(String.format("%d[name:%s,age:%d]", id, name, age));
}
}
}
关于如何使用 JDBC 和 Java API 的数据库连接池操作数据库,可以看。
整合 Activiti
添加依赖:
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter</artifactId>
<version>8.7.0</version>
</dependency>
注意,该依赖部署在 alfresco 公共仓库,而非通常的 Maven 中央仓库。
Activiti 和 Spring Boot 有版本对应关系,Spring Boot 2.X 应当使用 Activiti 7.X,而 Spring Boot 3.X 应当使用 Activiti 8.X,我这里使用的是当前的最新版本:
-
Spring Boot 3.4.5
-
Activiti 8.7.0
Activiti 项目使用 Java 21 构建,并且在 Gtihub 项目文档中明确要求使用 Java 21 以上版本,因此这里将项目的 Java 语言级别改为 21:
<properties>
<java.version>21</java.version>
</properties>
项目的 JDK 同样使用 21 版本的:
刷新 Maven 工具处理依赖并编译项目。如果出错,可能是远程仓库配置有误,可以参考。
导入 Activiti 相关表。
如何从 Activiti Jar 包中找表结构创建 SQL 可以参考。
原则上来说可以通过配置在应用启动时让 Activiti 自动检查和创建表结构,但是我从来没有成功过...
修改配置文件,添加 Activiti 相关配置信息:
spring
activiti
database-schema-update true # 应用启动后自动更新 activiti 表结构
db-history-used true # 记录 activiti 历史信息
history-level full # 记录所有的历史信息
check-process-definitions true # 自动检查 processes 目录下的 bpmn 文件部署
process-definition-location-prefix classpath /processes/ # 默认保存 bpmn 文件的位置
process-definition-location-suffixes'**.bpmn''**.bpmn20.xml' # bpmn 文件的后缀名
在资源目录resources/processes
下添加测试用的 BPMN 文件 和 PNG 文件 。
Acitiviti 使用 Spring-security 进行权限控制,如果在项目中不需要 Spring Security,可以通过以下方式禁用。
排除 Spring Security 相关依赖:
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter</artifactId>
<version>8.7.0</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</exclusion>
</exclusions>
</dependency>
修改配置文件,禁用 Spring Security 自动配置:
spring
autoconfigure
exclude org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,org.activiti.spring.boot.SecurityAutoConfiguration
通过配置类创建一个空的UserDetailsService
Bean:
public class ActivitiSecurityOverrideConfig {
public UserDetailsService userDetailsService() {
return username -> {
throw new UnsupportedOperationException("Security is disabled");
};
}
public UserGroupManager userGroupManager() {
return new UserGroupManager() {
public List<String> getUserGroups(String userId) {
return Collections.emptyList();
}
public List<String> getUserRoles(String userId) {
return Collections.emptyList();
}
public List<String> getGroups() {
return null;
}
public List<String> getUsers() {
return null;
}
};
}
}
测试:
public class ActivitiTests {
private RepositoryService repositoryService;
public void test() {
List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery()
.list();
for (ProcessDefinition processDefinition : list) {
log.info(String.format("流程定义ID:%s,名称:%s, Key:%s",
processDefinition.getId(),
processDefinition.getName(),
processDefinition.getKey()));
}
}
}
本文中完整的示例代码可以从获取。
文章评论