一、为什么需要容器集成?——引擎的“自动驾驶模式”
1. 传统模式 vs 容器模式
对比项 | 传统模式(手动挡) | Spring容器模式(自动挡) |
---|---|---|
流程引擎创建 | 手动编码初始化 | Spring自动装配ProcessEngine Bean |
事务管理 | 手动控制提交/回滚 | @Transactional 注解自动管理 |
依赖注入 | 手动获取Service | @Autowired 直接注入Service |
核心目标:让开发者专注业务逻辑,告别繁琐的引擎配置!
二、Spring整合三步曲——引擎的“上牌仪式”
1. 添加Spring依赖
在pom.xml
中注入Spring与Activiti整合包:
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring</artifactId>
<version>5.22.0</version> <!-- 与原书版本一致 -->
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.10</version>
</dependency>
2. 配置Spring容器
创建applicationContext.xml
,定义流程引擎与事务管理器:
<!-- 数据源配置 -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
<property name="driverClass" value="org.h2.Driver"/>
<property name="url" value="jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000"/>
<property name="username" value="sa"/>
<property name="password" value=""/>
</bean>
<!-- 事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<!-- Activiti流程引擎 -->
<bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
<property name="dataSource" ref="dataSource"/>
<property name="transactionManager" ref="transactionManager"/>
<property name="databaseSchemaUpdate" value="true"/>
</bean>
<bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
<property name="processEngineConfiguration" ref="processEngineConfiguration"/>
</bean>
<!-- 暴露Service Bean -->
<bean id="repositoryService" factory-bean="processEngine" factory-method="getRepositoryService"/>
<bean id="runtimeService" factory-bean="processEngine" factory-method="getRuntimeService"/>
3. 注入Service Bean
在代码中直接使用@Autowired
调用服务:
@Autowired
private RuntimeService runtimeService;
public void startProcess() {
ProcessInstance instance = runtimeService.startProcessInstanceByKey("leaveProcess");
}
三、事务管理——流程的“安全带”
1. 声明式事务控制
使用@Transactional
注解保证流程操作的原子性:
@Service
public class LeaveService {
@Autowired
private RuntimeService runtimeService;
@Transactional
public void startAndCompleteProcess() {
ProcessInstance instance = runtimeService.startProcessInstanceByKey("leaveProcess");
Task task = taskService.createTaskQuery().processInstanceId(instance.getId()).singleResult();
taskService.complete(task.getId());
}
}
2. 事务回滚测试
若流程执行中抛出异常,Spring会自动回滚数据库操作:
@Transactional
public void startProcessWithException() {
runtimeService.startProcessInstanceByKey("leaveProcess");
throw new RuntimeException("模拟异常"); // 流程启动操作将被回滚
}
四、与Spring其他模块的“联合作战”
1. 整合Spring Security
控制任务权限:
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests()
.antMatchers("/task/**").hasRole("USER")
.anyRequest().permitAll();
}
}
2. 整合Spring Boot
简化配置(原书可能未涉及,此处简要扩展):
# application.yml
spring:
activiti:
database-schema-update: true
check-process-definitions: false
datasource:
url: jdbc:h2:mem:activiti
driver-class-name: org.h2.Driver
username: sa
password:
五、避坑指南——容器集成的“暗礁”
1. Bean注入失败
症状:@Autowired
的Service为null
。
检查项:
- 是否在Spring配置文件中正确定义了Service Bean(如
repositoryService
)。 - 是否添加了
<context:component-scan>
扫描注解类。
2. 事务不生效
症状:异常后流程数据未回滚。
解法:
- 确保使用
@Transactional
注解,并启用事务管理器。 - 检查方法是否为
public
(Spring事务代理要求)。
六、课后挑战——巩固你的“容器驾照”
-
选择题:Spring整合后,如何获取
TaskService
?
A.ProcessEngines.getDefaultProcessEngine().getTaskService()
B.@Autowired private TaskService taskService
C. 手动从ProcessEngine
实例获取 -
实战题:在Spring容器中配置Activiti引擎,并实现一个定时任务自动清理历史数据(使用
@Scheduled
注解)。