Auto configuration data source of Springboot2.x

Keywords: Spring Tomcat Apache JDBC

DataSourceAutoConfiguration

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
@EnableConfigurationProperties(DataSourceProperties.class)
@Import({ DataSourcePoolMetadataProvidersConfiguration.class, DataSourceInitializationConfiguration.class })
public class DataSourceAutoConfiguration {

	@Configuration(proxyBeanMethods = false)
	//Determine whether to import the built-in database: H2, DERBY, HSQL
	@Conditional(EmbeddedDatabaseCondition.class)
	@ConditionalOnMissingBean({ DataSource.class, XADataSource.class })
	@Import(EmbeddedDataSourceConfiguration.class)
	protected static class EmbeddedDatabaseConfiguration {

	}

	@Configuration(proxyBeanMethods = false)
	//Determine whether to introduce dependent data sources: HikariDataSource, tomcat.jdbc.pool.DataSource, BasicDataSource
	@Conditional(PooledDataSourceCondition.class)
	@ConditionalOnMissingBean({ DataSource.class, XADataSource.class })
	//If the dependencies of Hikari, Tomcat, Dbcp2 and other data sources are imported at the same time, the priority of Hikari data sources is the highest, and Hikari data sources are registered
	//Other data sources will not be registered
	@Import({ DataSourceConfiguration.Hikari.class, DataSourceConfiguration.Tomcat.class,
			DataSourceConfiguration.Dbcp2.class, DataSourceConfiguration.Generic.class,
			DataSourceJmxConfiguration.class })
	protected static class PooledDataSourceConfiguration {

	}

See the pooledatasourceconfiguration class of the configuration data source, and Import some internal classes in the DataSourceConfiguration through the Import annotation.

DataSourceConfiguration

You can see that there are three data sources injected into the container, which are supported by springboot by default

  • org.apache.tomcat.jdbc.pool.DataSource
  • com.zaxxer.hikari.HikariDataSource
  • org.apache.commons.dbcp2.BasicDataSource

However, the premise to inject each data source is to meet some conditions:
1.@ConditionalOnClass condition, what do you mean? Import the corresponding dependency of each data source.
mybatis automatically imports the HikariDataSource data source. org.apache.tomcat.jdbc.pool.DataSource and org.apache.commons.dbcp2.BasicDataSource are not imported, so the default data source is the HikariDataSource data source. If we want to use other data sources, we should first exclude the HikariDataSource data source, and then import the dependence of other data sources.

The second condition to be satisfied is @ ConditionalOnMissingBean(DataSource.class). There is no data source component in the container
The third condition to be satisfied is @ ConditionalOnProperty. Take Hikari datasource as an example. If spring.datasource.type is not configured in the configuration file, then spring.datasource.type=com.zaxxer.hikari.HikariDataSource. If spring.datasource.type is configured, then the condition is satisfied.
After all the above three conditions are met, you can import the corresponding data source into the container through the @ Bean annotation.

abstract class DataSourceConfiguration {
	. . . 
	//HikariDataSource data source
	@Configuration(proxyBeanMethods = false)
	//Import HikariDataSource dependency
	@ConditionalOnClass(HikariDataSource.class)
	//Data source component does not exist in container
	@ConditionalOnMissingBean(DataSource.class)
	//If spring.datasource.type is not configured in the configuration file, spring.datasource.type=com.zaxxer.hikari.HikariDataSource
	//If spring.datasource.type is configured to be equal to com.zaxxer.hikari.HikariDataSource, the condition is met
	@ConditionalOnProperty(name = "spring.datasource.type", havingValue = "com.zaxxer.hikari.HikariDataSource",
			matchIfMissing = true)
	static class Hikari {
		@Bean
		@ConfigurationProperties(prefix = "spring.datasource.hikari")
		HikariDataSource dataSource(DataSourceProperties properties) {
			HikariDataSource dataSource = createDataSource(properties, HikariDataSource.class);
			if (StringUtils.hasText(properties.getName())) {
				dataSource.setPoolName(properties.getName());
			}
			return dataSource;
		}
	}
. . . 
	//If you are not using the three data sources that spring boot supports by default, register the data source components here
	@Configuration(proxyBeanMethods = false)
	@ConditionalOnMissingBean(DataSource.class)
	@ConditionalOnProperty(name = "spring.datasource.type")
	static class Generic {
		@Bean
		DataSource dataSource(DataSourceProperties properties) {
			return properties.initializeDataSourceBuilder().build();
		}
	}
}

Conclusion:
Mybatis spring boot starter supports HikariDataSource by default Data source. If we want to use other data sources, we just need to exclude the HikariDataSource data source and import other data sources. If we import the data sources supported by springboot, we don't need to configure spring.datasource.type =. If the other data sources are not supported by springboot, such as c3p0, we need to configure spring.datasource.type = Co m.mchange.v2.c3p0.ComboPooledDataSource.

Attach other data sources:

<!--c3p0-->
<!--<dependency>-->
    <!--<groupId>com.mchange</groupId>-->
    <!--<artifactId>c3p0</artifactId>-->
    <!--<version>0.9.5.5</version>-->
<!--</dependency>-->

<!--tomcat-jdbc data source-->
<dependency>
    <groupId>org.apache.tomcat</groupId>
    <artifactId>tomcat-jdbc</artifactId>
    <version>9.0.31</version>
</dependency>
<!--dbcp2 data source-->
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-dbcp2</artifactId>
    <version>2.7.0</version>
</dependency>
Published 83 original articles, won praise 13, visited 30000+
Private letter follow

Posted by jrobles on Sun, 23 Feb 2020 03:04:52 -0800