springboot在整合activiti時(shí),會(huì)有一些官方bug。那么接下來將講述如何springboot2.x完美整合activiti。
如果想直接看如何解決以及整合步驟不需要知道原理,請直接看末尾總結(jié)
一、引入pom文件
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter-basic</artifactId>
<version>6.0.0</version>
</dependency>
二、配置數(shù)據(jù)源
spring:
datasource:
url: jdbc:mysql://localhost:3306/db_activiti
username: root
password: 1234
driver-class-name: com.mysql.jdbc.Driver
至此一般來講,應(yīng)該是可以啟動(dòng)項(xiàng)目的。接下來啟動(dòng)試一試
發(fā)現(xiàn)啟動(dòng)出錯(cuò),這里放一些出錯(cuò)代碼
Failed to introspect annotations on class org.activiti.spring.boot.SecurityAutoConfiguration$$EnhancerBySpringCGLIB$$d26f5901
Failed to introspect annotations on class org.activiti.spring.boot.SecurityAutoConfiguration$$EnhancerBySpringCGLIB$$d26f5901
從上述代碼可知是在初始化SecurityAutoConfiguration的時(shí)候出現(xiàn)錯(cuò)誤,那么我們一般也不需要Security這個(gè)框架,直接將此配置類給排除掉,就可以了。
@SpringBootApplication(exclude = {org.activiti.spring.boot.SecurityAutoConfiguration.class})
我們再來啟動(dòng),發(fā)現(xiàn)還是有問題,那么這次問題是什么呢?
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.activiti.spring.SpringProcessEngineConfiguration]
Caused by: java.io.FileNotFoundException: class path resource [processes/] cannot be resolved to URL because it does not exist
看起來好像是由于根目錄下的processes文件夾沒有找到而報(bào)錯(cuò),顧名思義,一看這應(yīng)該是activiti默認(rèn)將根目錄下的processes文件夾作為統(tǒng)一放置流程資源文件的地方。
那么如何解決呢?這里有兩種解決辦法
- 第一種
第一種當(dāng)然很簡單了,既然processes文件夾找不到,直接創(chuàng)建一個(gè)就好了唄
- 第二種
通過源碼來分析,既然是org.activiti.spring.SpringProcessEngineConfiguration構(gòu)建失敗,那么繼續(xù)看出錯(cuò):
at org.activiti.spring.boot.DataSourceProcessEngineAutoConfiguration$DataSourceProcessEngineConfiguration.springProcessEngineConfiguration(DataSourceProcessEngineAutoConfiguration.java:57) ~[activiti-spring-boot-starter-basic-6.0.0.jar:na]
可知org.activiti.spring.SpringProcessEngineConfiguration是由org.activiti.spring.boot.DataSourceProcessEngineAutoConfiguration來構(gòu)建,那么我們在這個(gè)類中打個(gè)斷點(diǎn),查看構(gòu)建邏輯。
- DataSourceProcessEngineAutoConfiguration.java
@Bean
@ConditionalOnMissingBean
public SpringProcessEngineConfiguration springProcessEngineConfiguration(DataSource dataSource, PlatformTransactionManager transactionManager, SpringAsyncExecutor springAsyncExecutor) throws IOException {
return this.baseSpringProcessEngineConfiguration(dataSource, transactionManager, springAsyncExecutor);
}
進(jìn)入這個(gè)方式之后走到了AbstractProcessEngineAutoConfiguration的baseSpringProcessEngineConfiguration邏輯中
- AbstractProcessEngineAutoConfiguration.java
protected SpringProcessEngineConfiguration baseSpringProcessEngineConfiguration(DataSource dataSource, PlatformTransactionManager platformTransactionManager, SpringAsyncExecutor springAsyncExecutor) throws IOException {
List<Resource> procDefResources = this.discoverProcessDefinitionResources(this.resourceLoader, this.activitiProperties.getProcessDefinitionLocationPrefix(), this.activitiProperties.getProcessDefinitionLocationSuffixes(), this.activitiProperties.isCheckProcessDefinitions());
.......
...
..
}
查看discoverProcessDefinitionResources實(shí)現(xiàn)
public List<Resource> discoverProcessDefinitionResources(ResourcePatternResolver applicationContext, String prefix, List<String> suffixes, boolean checkPDs) throws IOException {
if (!checkPDs) {
return new ArrayList();
} else {
List<Resource> result = new ArrayList();
Iterator var6 = suffixes.iterator();
while(true) {
Resource[] resources;
do {
do {
if (!var6.hasNext()) {
if (result.isEmpty()) {
logger.info(String.format("No process definitions were found for autodeployment"));
}
return result;
}
String suffix = (String)var6.next();
String path = prefix + suffix;
resources = applicationContext.getResources(path);
} while(resources == null);
} while(resources.length <= 0);
Resource[] var10 = resources;
int var11 = resources.length;
for(int var12 = 0; var12 < var11; ++var12) {
Resource resource = var10[var12];
result.add(resource);
}
}
}
}
首先對調(diào)用上述discoverProcessDefinitionResources方式時(shí)的參數(shù)的值進(jìn)行說明
this.processDefinitionLocationPrefix = "classpath:/processes/";
this.processDefinitionLocationSuffixes = Arrays.asList("**.bpmn20.xml", "**.bpmn");
private boolean checkProcessDefinitions = true;
所以也就是當(dāng)checkProcessDefinitions為true時(shí),將獲取所有根目錄下processes文件下后綴.bpmn20.xml和.bpmn的所有資源,否則直接返回一個(gè)空的resource集合。到這里想必已經(jīng)知道怎么改了,直接設(shè)置checkProcessDefinitions為false,讓它在初始化啟動(dòng)時(shí)不從processes文件夾下加載資源就可以了。
只需要在application.yml添加
spring:
activiti:
check-process-definitions: false
此時(shí)查看數(shù)據(jù)庫中,activiti的表已經(jīng)創(chuàng)建好啦!
三、總結(jié)
springboot2.x整合activiti6.0步驟
- 第一步:加入pom依賴
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter-basic</artifactId>
<version>6.0.0</version>
</dependency>
-
第二步:排除org.activiti.spring.boot.SecurityAutoConfiguration的構(gòu)建
啟動(dòng)類注解上添加配置
@SpringBootApplication(exclude = {org.activiti.spring.boot.SecurityAutoConfiguration.class})
- 第三步:在classpath下添加processes文件夾或者在application.yml中添加配置
spring:
activiti:
check-process-definitions: false