Spring Boot实现了自动加载DataSource及相关配置。当然,使用时加上@EnableAutoConfiguration注解是必须的。下面就是对这一部分的源码分析。
(1)Spring Boot启动后会调用org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration。下面是部分源码。
1 @Configuration 2 @ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class }) 3 @EnableConfigurationProperties(DataSourceProperties.class) 4 @Import({ DataSourcePoolMetadataProvidersConfiguration.class, 5 DataSourceInitializationConfiguration.class }) 6 public class DataSourceAutoConfiguration { 7 8 @Configuration 9 @Conditional(EmbeddedDatabaseCondition.class) 10 @ConditionalOnMissingBean({ DataSource.class, XADataSource.class }) 11 @Import(EmbeddedDataSourceConfiguration.class) 12 protected static class EmbeddedDatabaseConfiguration { 13 } 14 15 @Configuration 16 @Conditional(PooledDataSourceCondition.class) 17 @ConditionalOnMissingBean({ DataSource.class, XADataSource.class }) 18 @Import({ DataSourceConfiguration.Hikari.class, DataSourceConfiguration.Tomcat.class, 19 DataSourceConfiguration.Dbcp2.class, DataSourceConfiguration.Generic.class, 20 DataSourceJmxConfiguration.class }) 21 protected static class PooledDataSourceConfiguration { 22 } 23 ...... 24 }
我们从中可以看出,DataSourceAutoConfiguration中有两个嵌套类,一个是EmbeddedDatabaseConfiguration,另一个是PooledDataSourceConfiguration。
EmbeddedDatabaseConfiguration表示已经嵌入Spring Boot的DataSource,除了Maven中加入相应的Driver,可以不做其他额外配置就能使用。从EmbeddedDatabaseType类可以看出,Spring Boot的内嵌DataSource支持HSQL,H2,DERBY这三种DB。
PooledDataSourceConfiguration表示Spring Boot还支持一些实现Pool的DataSource。从org.springframework.boot.jdbc.DataSourceBuilder中可以看出,当前版本的Spring Boot(2.0)只支持com.zaxxer.hikari.HikariDataSource,org.apache.tomcat.jdbc.pool.DataSource,org.apache.commons.dbcp2.BasicDataSource。其中,性能更加优秀的HikariDataSource是Spring Boot的默认选择(DataSourceBuilder中DATA_SOURCE_TYPE_NAMES[0]=com.zaxxer.hikari.HikariDataSource)。所以,当application.yml文件中做如下配置时,Spring Boot默认使用HikariDataSource数据库连接池。
spring: datasource: url: jdbc:mysql://localhost:3306/sas username: root password: **** driver-class-name: com.mysql.jdbc.Driver #type: com.zaxxer.hikari.HikariDataSource
(2)我们以HikariDataSource举例,接下来调用PooledDataSourceConfiguration中org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration抽象类的Hikari嵌套类(DataSourceConfiguration抽象类的一个实现类)。
1 abstract class DataSourceConfiguration { 2 3 @SuppressWarnings("unchecked") 4 protected <T> T createDataSource(DataSourceProperties properties, 5 Class<? extends DataSource> type) { 6 return (T) properties.initializeDataSourceBuilder().type(type).build(); 7 } 8 9 /* Omit Tomcat Pool DataSource configuration.*/ 10 /** 11 * Hikari DataSource configuration. 12 */ 13 @ConditionalOnClass(HikariDataSource.class) 14 @ConditionalOnProperty(name = "spring.datasource.type", havingValue = "com.zaxxer.hikari.HikariDataSource", matchIfMissing = true) 15 static class Hikari extends DataSourceConfiguration { 16 17 @Bean 18 @ConfigurationProperties(prefix = "spring.datasource.hikari") 19 public HikariDataSource dataSource(DataSourceProperties properties) { 20 HikariDataSource dataSource = createDataSource(properties, 21 HikariDataSource.class); 22 if (StringUtils.hasText(properties.getName())) { 23 dataSource.setPoolName(properties.getName()); 24 } 25 return dataSource; 26 } 27 } 28 /* Omit DBCP DataSource configuration.*/ 29 }
我们从黄色部分可以看出,当application.yml文件中配置spring.datasource.type=com.zaxxer.hikari.HikariDataSource时,会使用HikariDataSource作为数据库连接池。它会