Multiple data sources start abnormally: No qualifying bean of type 'javax.sql.DataSource' available: more than one 'primary' bean f


Multi-data source error: No qualifying bean of type 'javax.sql.DataSource' available: more than one 'primary' bean found among candidates: [test2DataSource, test1DataSource] Pom was introduced when mybatis was introduced before

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-autoconfigure</artifactId>
</dependency>

Spring will rely on the spring-boot-autoconfigure
jar package. There is a DataSourceAutoConfiguration in this jar package that will initialize the DataSourceInitializer class. This class has an init method to get the DataSource (data source)

@Configuration
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
@EnableConfigurationProperties(DataSourceProperties.class)
@Import({ Registrar.class, DataSourcePoolMetadataProvidersConfiguration.class })
public class DataSourceAutoConfiguration {
 
@Configuration
@ConditionalOnMissingBean(DataSourceInitializer.class)
protected static class DataSourceInitializerConfiguration {
 
@Bean
public DataSourceInitializer dataSourceInitializer() {
return new DataSourceInitializer();
}


The data source will be obtained in the initialization method. Some ddl operations need to be initialized. The runSchemaScripts () method checks whether sql script needs to be executed during initialization. When you have two data sources, the program does not know which one to take, so the error is reported.

@PostConstruct
public void init() {
if (!this.properties.isInitialize()) {
logger.debug("Initialization disabled (not running DDL scripts)");
      return;
}
if (this.applicationContext.getBeanNamesForType(DataSource.class, false, false).length > 0) {
this.dataSource = this.applicationContext.getBean(DataSource.class);
}
if (this.dataSource == null) {
logger.debug("No DataSource found so not initializing");
      return;
}
   runSchemaScripts();
}
 
private void runSchemaScripts() {
   List<Resource> scripts = getScripts(this.properties.getSchema(), "schema");
   if (!scripts.isEmpty()) {
      runScripts(scripts);
      try {
this.applicationContext.publishEvent(new DataSourceInitializedEvent(
this.dataSource));
// The listener might not be registered yet, so don't rely on it.
if (!this.initialized) {
            runDataScripts();
            this.initialized = true;
}
      }
catch (IllegalStateException ex) {
logger.warn("Could not send event to complete DataSource initialization ("
+ ex.getMessage() + ")");
}
   }
}

Solution:
If it is an xml configuration, 
add a primary = "true" to the place where the data source is defined. Remember to add only one of them. When there are multiple data sources, mark this data source as the main one.

<bean id="payment-dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close" primary="true">

If it is a spring boot project, the
spring boot startup class plus exclude = DataSourceAutoConfiguration.class means that this class is not loaded when starting the project.
Example:


@ComponentScan(basePackages = "com.pinyu.system")
@MapperScan("com.pinyu.system.mapper")
@EnableTransactionManagement
@SpringBootApplication(exclude={  
        DataSourceAutoConfiguration.class,  
//        HibernateJpaAutoConfiguration.class, //(如果使用Hibernate时,需要加)  
        DataSourceTransactionManagerAutoConfiguration.class,  
        })
public class Application extends SpringBootServletInitializer {
 
}

Original link: https://blog.csdn.net/ypp91zr/article/details/84298861

Published 81 original articles · Like1 · Visits 30,000+

Guess you like

Origin blog.csdn.net/xiaoanzi123/article/details/105094059
Recommended