背景:原架构Springboot + Mybatis + Ignite 持久化
在上面的架构中想引入Camunda Engine + H2嵌入式。因为Camunda必须有一个关系型数据库,Ignite不是关系型数据库,所以想要引入Camunda,就需要再引入一个新的数据源来支持Camunda Engine的运行,因为对Camunda的使用场景只是用它的process engine核心,不需要用户管理、权限那一套,且不保存历史数据,所以选择嵌入式H2就行。
出现了一个小问题就是,跑起来之后,打印ProcessEngineConfiguration的jdbcUrl,一直显示“jdbc:h2:tcp://localhost/activiti”(不是我的配置的内容),让我一度以为datasource没有注入成功,之后debug,并看了看源码发现。这个现象是正常的。理由是如果datasource对象不为空,那会直接用datasource,否则它会用零散的jdbcDriver, jdbcUrl, jdbcUsername, jdbcPassword这些属性自己创建一个连接池,并指向datasource。所以想要知道真正的连接信息,是需要看datasource中的内容。
源码
一、org.camunda.bpm.engine.ProcessEngineConfiguration中有如下属性:
protected String jdbcDriver = "org.h2.Driver";
protected String jdbcUrl = "jdbc:h2:tcp://localhost/activiti";
protected String jdbcUsername = "sa";
protected String jdbcPassword = "";
protected String dataSourceJndiName = null;
………………
protected DataSource dataSource;
插件及对应顺序:
ENGINE-12003 Plugin 'CompositeProcessEnginePlugin[genericPropertiesConfiguration, camundaProcessEngineConfiguration, camundaDatasourceConfiguration, camundaJobConfiguration, camundaHistoryConfiguration, camundaMetricsConfiguration, camundaAuthorizationConfiguration, failedJobConfiguration, disableDeploymentResourcePattern, eventPublisherPlugin]' activated on process engine 'default'
二、通过调用processEngineConfiguration.buildProcessEngine(),会调用processEngineConfigurationImpl.init(),初始化一系列内容,其中第一个invokePreInit()中,会挨个遍历processEnginePlugins中的所有插件,并执行插件的preInit()方法。第一个插件是genericPropertiesConfiguration(应该是注解application.properties中的参数),第三个camundaDatasourceConfiguration插件最终会去执行DefaultDatasourceConfiguration.preInit,这里会判断是否有注入过 camundaBpmDataSource 这个对象,如果有,会把他设置到processEngineConfiguration的dataSource中;
@Qualifier("camundaBpmDataSource")
protected DataSource camundaDataSource;
三、processEngineConfigurationImpl.init()中的initDataSource(),首先会判断dataSource是否空,如果空,那么会优先根据dataSourceJndiName创建datasource,否则会根据 jdbcDriver, jdbcUrl, jdbcUsername, jdbcPassword创建出一个PooledDataSource连接池(This is a simple, synchronous, thread-safe database connection pool.),并赋值给processEngineConfiguration的dataSource。
pom.xml
<h2.version>1.4.197</h2.version>
<camunda.version>7.13.0</camunda.version>
…………
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>${h2.version}</version>
</dependency>
<dependency>
<groupId>org.camunda.bpm.springboot</groupId>
<artifactId>camunda-bpm-spring-boot-starter</artifactId>
<version>${camunda.version}</version>
</dependency>
……
application.properties
…………
#logic datasource
spring.datasource.driver-class-name=org.apache.ignite.IgniteJdbcThinDriver
spring.datasource.url=jdbc:ignite:thin://xx.xx.xx.xx/
spring.datasource.username=ignite
spring.datasource.password=ignite
#default HikariDataSource
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.maximum-pool-size=15
#default TRUE
spring.datasource.hikari.auto-commit=true
#defult 600000
spring.datasource.hikari.idle-timeout=30000
#default HikariPool-1
spring.datasource.hikari.pool-name=DatebookHikariCP
#default 1800000
#spring.datasource.hikari.max-lifetime=1800000
#default 30000
#spring.datasource.hikari.connection-timeout=30000
spring.datasource.hikari.connection-test-query=SELECT 1
#camunda datasource
camunda.bpm.datasource.driver-class-name=org.h2.Driver
camunda.bpm.datasource.url=jdbc:h2:./camunda;MVCC=TRUE;TRACE_LEVEL_FILE=0;DB_CLOSE_ON_EXIT=FALSE
camunda.bpm.datasource.username=sa
camunda.bpm.datasource.password=sa
camunda.bpm.datasource.type=com.zaxxer.hikari.HikariDataSource
camunda.bpm.datasource.hikari.pool-name=DatebookHikariCP_H2
camunda.bpm.datasource.hikari.minimum-idle=1
camunda.bpm.datasource.hikari.maximum-pool-size=8
camunda.bpm.datasource.hikari.idle-timeout=12300
camunda.bpm.datasource.hikari.connection-timeout=45600
camunda.bpm.process-engine-name=TEST
camunda.bpm.history-level=NONE
camunda.bpm.database.schema-update=true
camunda.bpm.database.type=h2
camunda.bpm.webapp.enabled=false
camunda.bpm.authorization.enabled=false
#mybatis
mybatis.config-location=classpath:mybatis/mybatis.cfg.xml
mybatis.type-aliases-package=com.abc.demo.model
mybatis.mapper-locations=classpath:mybatis/mapping/*.xml
application.java
@SpringBootApplication
@EnableProcessApplication
@ImportResource("classpath:applicationContext.xml")
public class Application {
private static final Logger logger = LoggerFactory.getLogger(Application.class);
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
配置数据源-业务数据源
@Configuration
public class FirstDataSourceConfiguration {
@Bean
@Primary
@ConfigurationProperties("spring.datasource")
public DataSourceProperties firstDataSourceProperties() {
return new DataSourceProperties();
}
@Bean
@Primary
@ConfigurationProperties("spring.datasource.hikari")
public DataSource firstDataSource() {
return firstDataSourceProperties().initializeDataSourceBuilder().build();
}
@Bean
@Primary
public PlatformTransactionManager firstTransactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
配置Camunda数据源
@Configuration
public class SecondDataSourceConfiguration {
@Bean
@ConfigurationProperties("camunda.bpm.datasource")
public DataSourceProperties secondDataSourceProperties() {
return new DataSourceProperties();
}
@Bean(name="camundaBpmDataSource")
@ConfigurationProperties("camunda.bpm.datasource.hikari")
public DataSource secondDataSource() {
return secondDataSourceProperties().initializeDataSourceBuilder().build();
}
@Bean(name="camundaBpmTransactionManager")
public PlatformTransactionManager secondTransactionManager(@Qualifier("camundaBpmDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
其余信息略