No qualifying bean of type 'javax.sql.DataSource' available: more than one 'primary' bean found amon
阿新 • • 發佈:2018-12-11
多資料來源報錯:No qualifying bean of type 'javax.sql.DataSource' available: more than one 'primary' bean found among candidates: [test2DataSource, test1DataSource]由於之前引入mybatis的時候引入了pom
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-autoconfigure</artifactId> </dependency>
spring會依賴spring-boot-autoconfigure這個jar包
這個jar包中 有個DataSourceAutoConfiguration 會初始化DataSourceInitializer 這個類 ,這個類有一個init方法 會去獲取DataSource(資料來源)
@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(); }
初始化方法中 會獲取資料來源 需要初始化一些ddl操作 也是就runSchemaScripts()方法 檢查初始化時是否需要執行sql script ,當你有兩個資料來源的時候,程式不知道取哪一個 ,所以報錯
@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() + ")"); } } }
解決辦法:
如果是xml配置的話
定義資料來源的地方 加個primary="true" 記得只給其中的一個加, 當多資料來源時 標示這個資料來源是主要的
<bean id="payment-dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close" primary="true">
如果是spring boot專案
spring boot 啟動類加上 exclude = DataSourceAutoConfiguration.class 代表啟動專案的時候 不載入這個類
例子:
@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 {
}