spring boot自动装配hikari的步骤

 

1. 

spring-boot-starter-jdbc 里引入了 hikari 依赖:

    <dependency>
      <groupId>com.zaxxer</groupId>
      <artifactId>HikariCP</artifactId>
      <version>5.1.0</version>
      <scope>compile</scope>
    </dependency>

 

2. spring-boot-starter 里引入 spring-boot-autoconfigure 依赖.

autoconfigure的META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports 该类正式开始引入了`DataSourceConfiguration`

org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
package org.springframework.boot.autoconfigure.jdbc;

@AutoConfiguration(before = SqlInitializationAutoConfiguration.class)
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
@ConditionalOnMissingBean(type = "io.r2dbc.spi.ConnectionFactory")

@EnableConfigurationProperties(DataSourceProperties.class)

//@ConfigurationProperties(prefix = "spring.datasource") 
//声明 DataSourceProperties 类是一个 @ConfigurationProperties 类,并将其注册为 Spring 容器中的 Bean。


@Import({ DataSourcePoolMetadataProvidersConfiguration.class, DataSourceCheckpointRestoreConfiguration.class })
public class DataSourceAutoConfiguration {

	@Configuration(proxyBeanMethods = false)
	@Conditional(EmbeddedDatabaseCondition.class)
	@ConditionalOnMissingBean({ DataSource.class, XADataSource.class })
	@Import(EmbeddedDataSourceConfiguration.class)
	protected static class EmbeddedDatabaseConfiguration {

	}

	@Configuration(proxyBeanMethods = false)
	@Conditional(PooledDataSourceCondition.class)
	@ConditionalOnMissingBean({ DataSource.class, XADataSource.class })
	//手动定义DataSource时不再加载这个配置类.如自定义sqlite的DataSource配置时.
	
	@Import({ DataSourceConfiguration.Hikari.class, DataSourceConfiguration.Tomcat.class,
			DataSourceConfiguration.Dbcp2.class, DataSourceConfiguration.OracleUcp.class,
			DataSourceConfiguration.Generic.class, DataSourceJmxConfiguration.class })
			
	//导入其他配置类或组件到当前上下文中。
	//这些类分别对应不同的数据源实现(如 HikariCP、Tomcat JDBC Pool、Dbcp2 等)。
	//Spring Boot 会根据运行时条件(如依赖库的存在与否)选择合适的实现来加载数据源。
	
	
	protected static class PooledDataSourceConfiguration {

		@Bean
		@ConditionalOnMissingBean(JdbcConnectionDetails.class)
		PropertiesJdbcConnectionDetails jdbcConnectionDetails(DataSourceProperties properties) {
		
			//将 DataSourceProperties 对象封装为 PropertiesJdbcConnectionDetails 实例并返回。
			//PropertiesJdbcConnectionDetails 是一个辅助类,通常用于提取数据库连接信息(如 URL、用户名、密码等)。
			return new PropertiesJdbcConnectionDetails(properties);
		}

	}

	/**
	 * {@link AnyNestedCondition} that checks that either {@code spring.datasource.type}
	 * is set or {@link PooledDataSourceAvailableCondition} applies.
	 */
	static class PooledDataSourceCondition extends AnyNestedCondition {

		PooledDataSourceCondition() {
			super(ConfigurationPhase.PARSE_CONFIGURATION);
		}

		@ConditionalOnProperty(prefix = "spring.datasource", name = "type")
		static class ExplicitType {

		}

		@Conditional(PooledDataSourceAvailableCondition.class)
		static class PooledDataSourceAvailable {

		}

	}

	/**
	 * {@link Condition} to test if a supported connection pool is available.
	 */
	static class PooledDataSourceAvailableCondition extends SpringBootCondition {

		@Override
		public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
			ConditionMessage.Builder message = ConditionMessage.forCondition("PooledDataSource");
			if (DataSourceBuilder.findType(context.getClassLoader()) != null) {
				return ConditionOutcome.match(message.foundExactly("supported DataSource"));
			}
			return ConditionOutcome.noMatch(message.didNotFind("supported DataSource").atAll());
		}

	}

	/**
	 * {@link Condition} to detect when an embedded {@link DataSource} type can be used.
	 * If a pooled {@link DataSource} is available, it will always be preferred to an
	 * {@code EmbeddedDatabase}.
	 */
	static class EmbeddedDatabaseCondition extends SpringBootCondition {

		private static final String DATASOURCE_URL_PROPERTY = "spring.datasource.url";

		private final SpringBootCondition pooledCondition = new PooledDataSourceCondition();

		@Override
		public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {
			ConditionMessage.Builder message = ConditionMessage.forCondition("EmbeddedDataSource");
			if (hasDataSourceUrlProperty(context)) {
				return ConditionOutcome.noMatch(message.because(DATASOURCE_URL_PROPERTY + " is set"));
			}
			if (anyMatches(context, metadata, this.pooledCondition)) {
				return ConditionOutcome.noMatch(message.foundExactly("supported pooled data source"));
			}
			EmbeddedDatabaseType type = EmbeddedDatabaseConnection.get(context.getClassLoader()).getType();
			if (type == null) {
				return ConditionOutcome.noMatch(message.didNotFind("embedded database").atAll());
			}
			return ConditionOutcome.match(message.found("embedded database").items(type));
		}

		private boolean hasDataSourceUrlProperty(ConditionContext context) {
			Environment environment = context.getEnvironment();
			if (environment.containsProperty(DATASOURCE_URL_PROPERTY)) {
				try {
					return StringUtils.hasText(environment.getProperty(DATASOURCE_URL_PROPERTY));
				}
				catch (IllegalArgumentException ex) {
					// NOTE: This should be PlaceholderResolutionException
					// Ignore unresolvable placeholder errors
				}
			}
			return false;
		}

	}

}

 

### org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration

package org.springframework.boot.autoconfigure.jdbc;

abstract class DataSourceConfiguration {


		@Configuration(proxyBeanMethods = false)
		@ConditionalOnClass(HikariDataSource.class)
		@ConditionalOnMissingBean(DataSource.class)
		@ConditionalOnProperty(name = "spring.datasource.type", havingValue = "com.zaxxer.hikari.HikariDataSource",
				matchIfMissing = true)
				
		//如果显式设置了 spring.datasource.type=com.zaxxer.hikari.HikariDataSource,没有也行 `matchIfMissing = true`
		
		static class Hikari {

			@Bean
			static HikariJdbcConnectionDetailsBeanPostProcessor jdbcConnectionDetailsHikariBeanPostProcessor(
					ObjectProvider<JdbcConnectionDetails> connectionDetailsProvider) {
				return new HikariJdbcConnectionDetailsBeanPostProcessor(connectionDetailsProvider);
			}

			@Bean
			@ConfigurationProperties(prefix = "spring.datasource.hikari")
			//这里将 配置文件中 hukari的配置 自动包装到 HikariDataSource 里
			
			//这里就正式定义全局的 DataSource bean啦
			HikariDataSource dataSource(DataSourceProperties properties, JdbcConnectionDetails connectionDetails) {
				HikariDataSource dataSource = createDataSource(connectionDetails, HikariDataSource.class,
						properties.getClassLoader());
				if (StringUtils.hasText(properties.getName())) {
					dataSource.setPoolName(properties.getName());
				}
				return dataSource;
			}

		}
 
 ......
 }