框架:SpringBoot + Mybatis + Activiti7
思路:
单独给mybatis和activiti配置datasource
Mybati配置单数据源方法
单数据源只需要在yml中配置
url: jdbc:mysql://localhost:3306/localtest?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useSSL=false&nullCatalogMeansCurrent=true
driver-class-name: com.mysql.cj.jdbc.Driver
username: root
password: 123456
Mybati配置双数据源方法
给每个mybatis配置类分别设置数据源,然后使用MapperScan声明作用的mapper路径
此时url需要写成jdbc-url,不然会报错,欲知为何,待我看懂ConfigurationProperties咋起作用的
// 声明businessDataSource只作用于mapper路径下
@Configuration
@MapperScan(basePackages = "com.rsb.activitispringboot.mapper", sqlSessionFactoryRef = "businessSqlSessionFactory")
public class MybatisConfig {
@Bean(name = "businessDataSource")
@ConfigurationProperties(prefix = "spring.datasource.master")
public DataSource businessDataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "businessSqlSessionFactory")
public SqlSessionFactory bizSqlSessionFactory(@Qualifier("businessDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/*.xml"));
return bean.getObject();
}
@Bean(name = "businessSqlSessionTemplate")
public SqlSessionTemplate bizSqlSessionTemplate(@Qualifier("businessSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
activiti和mybaits分别配置数据源
activiti自己继承了mybaits,其mapper没有暴露,所以不能使用以上方法配置。
ativiti7有一个配置数据源的类ProcessEngineAutoConfiguration
@Bean
@ConditionalOnMissingBean // 不存在SpringProcessEngineConfiguration的bean的时候,才会注册这个bean
public SpringProcessEngineConfiguration springProcessEngineConfiguration(
DataSource dataSource,
PlatformTransactionManager transactionManager,
SpringAsyncExecutor springAsyncExecutor,
ActivitiProperties activitiProperties,
ProcessDefinitionResourceFinder processDefinitionResourceFinder,
@Autowired(required = false) List\<ProcessEngineConfigurationConfigurer> processEngineConfigurationConfigurers,
@Autowired(required = false) List\<ProcessEngineConfigurator> processEngineConfigurators) throws IOException {
conf.setDataSource(dataSource);
//...}
也就是说同时存在mybaits的BusinessDatasource和ActivitiDatSource,而IOC容器单例模式不能有两个相同的bean,除非name不同,所以就有2种思路。
- mybatis配置别名,activiti不配置
- activiti配置别名,mybaits配置/不配置
1) mybatis配置别名,activiti不配置,这种方式简单,不用实现activiti的复杂编码。优先加载activiti的数据源
@Primary其作用与功能,当有多个相同类型的bean时,使用@Primary来赋予bean更高的优先级
@Configuration
@MapperScan(basePackages = "com.rsb.activitispringboot.mapper", sqlSessionFactoryRef = "businessSqlSessionFactory")
public class MybatisConfig {
@Bean(name = "businessDataSource")
@ConfigurationProperties(prefix = "spring.datasource.master")
public DataSource businessDataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "businessSqlSessionFactory")
public SqlSessionFactory bizSqlSessionFactory(@Qualifier("businessDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/*.xml"));
return bean.getObject();
}
@Bean(name = "businessSqlSessionTemplate")
public SqlSessionTemplate bizSqlSessionTemplate(@Qualifier("businessSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
}
@Configuration
public class ActivitiConfig{
@Bean
@Primary
@ConfigurationProperties(prefix = "spring.activiti.datasource")
public DataSource activitiDataSource() {
return DataSourceBuilder.create().build();
}
}
2) activiti配置别名,mybaits不配置 / 不配置
mybatis配置同上,可以使用Qualifier 也可以使用@Primary,建议@Qualifier,清晰明了
@Configuration
public class ActivitiConfig extends AbstractProcessEngineAutoConfiguration {
@Bean("activitiDataSource")
@ConfigurationProperties(prefix = "spring.activiti.datasource")
public DataSource activitiDataSource() {
return DataSourceBuilder.create().build();
}
@Bean("activitiTransactionManager")
public PlatformTransactionManager txManager(@Qualifier("activitiDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean
public SpringProcessEngineConfiguration springProcessEngineConfiguration(
@Qualifier("activitiDataSource") DataSource dataSource,
@Qualifier("activitiTransactionManager") PlatformTransactionManager transactionManager,
SpringAsyncExecutor springAsyncExecutor,
ActivitiProperties activitiProperties,
ProcessDefinitionResourceFinder processDefinitionResourceFinder,
@Autowired(required = false) List\<ProcessEngineConfigurationConfigurer> processEngineConfigurationConfigurers,
@Autowired(required = false) List\<ProcessEngineConfigurator> processEngineConfigurators) throws IOException {
SpringProcessEngineConfiguration conf = new SpringProcessEngineConfiguration();
conf.setConfigurators(processEngineConfigurators);
configureProcessDefinitionResources(processDefinitionResourceFinder,conf);
conf.setDataSource(dataSource);
conf.setTransactionManager(transactionManager);
if (springAsyncExecutor != null) {
conf.setAsyncExecutor(springAsyncExecutor);
}
conf.setDeploymentName(activitiProperties.getDeploymentName());
conf.setDatabaseSchema(activitiProperties.getDatabaseSchema()); >> conf.setDatabaseSchemaUpdate(activitiProperties.getDatabaseSchemaUpdate());
conf.setDbHistoryUsed(activitiProperties.isDbHistoryUsed());
conf.setAsyncExecutorActivate(activitiProperties.isAsyncExecutorActivate());
if (!activitiProperties.isAsyncExecutorActivate()) {
ValidatorSet springBootStarterValidatorSet = new ValidatorSet("activiti-spring-boot-starter");
springBootStarterValidatorSet.addValidator(new AsyncPropertyValidator());
if (conf.getProcessValidator() == null) {
ProcessValidatorImpl processValidator = new ProcessValidatorImpl();
processValidator.addValidatorSet(springBootStarterValidatorSet);
conf.setProcessValidator(processValidator);
} else {
conf.getProcessValidator().getValidatorSets().add(springBootStarterValidatorSet);
}
}
conf.setMailServerHost(activitiProperties.getMailServerHost());
conf.setMailServerPort(activitiProperties.getMailServerPort());
conf.setMailServerUsername(activitiProperties.getMailServerUserName());
conf.setMailServerPassword(activitiProperties.getMailServerPassword());
conf.setMailServerDefaultFrom(activitiProperties.getMailServerDefaultFrom());
conf.setMailServerUseSSL(activitiProperties.isMailServerUseSsl());
conf.setMailServerUseTLS(activitiProperties.isMailServerUseTls());
conf.setUserGroupManager(userGroupManager);
conf.setHistoryLevel(activitiProperties.getHistoryLevel());
conf.setCopyVariablesToLocalForTasks(activitiProperties.isCopyVariablesToLocalForTasks());
conf.setSerializePOJOsInVariablesToJson(activitiProperties.isSerializePOJOsInVariablesToJson());
conf.setJavaClassFieldForJackson(activitiProperties.getJavaClassFieldForJackson());
if (activitiProperties.getCustomMybatisMappers() != null) {
conf.setCustomMybatisMappers(
getCustomMybatisMapperClasses(activitiProperties.getCustomMybatisMappers()));
}
if (activitiProperties.getCustomMybatisXMLMappers() != null) {
conf.setCustomMybatisXMLMappers(new HashSet<>(activitiProperties.getCustomMybatisXMLMappers()));
}
if (activitiProperties.getCustomMybatisXMLMappers() != null) {
conf.setCustomMybatisXMLMappers(new HashSet<> activitiProperties.getCustomMybatisXMLMappers()));
}
if (activitiProperties.isUseStrongUuids()) {
conf.setIdGenerator(new StrongUuidGenerator());
}
if (activitiProperties.getDeploymentMode() != null) {
conf.setDeploymentMode(activitiProperties.getDeploymentMode());
}
conf.setActivityBehaviorFactory(new DefaultActivityBehaviorFactory());
if (processEngineConfigurationConfigurers != null) {
for (ProcessEngineConfigurationConfigurer processEngineConfigurationConfigurer : processEngineConfigurationConfigurers) {
processEngineConfigurationConfigurer.configure(conf);
}
}
return conf;
}
private void configureProcessDefinitionResources(
ProcessDefinitionResourceFinder processDefinitionResourceFinder,
SpringProcessEngineConfiguration conf) throws IOException {
List<Resource> procDefResources = processDefinitionResourceFinder.discoverProcessDefinitionResources();
if (!procDefResources.isEmpty()) {
conf.setDeploymentResources(procDefResources.toArray(new Resource\[0]));
}
}
}