DataSourceAutoConfiguration源码笔记
代码如下:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//package org.springframework.boot.autoconfigure.jdbc;import javax.sql.DataSource;
import javax.sql.XADataSource;
import org.springframework.boot.autoconfigure.condition.AnyNestedCondition;
import org.springframework.boot.autoconfigure.condition.ConditionMessage;
import org.springframework.boot.autoconfigure.condition.ConditionOutcome;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.SpringBootCondition;
import org.springframework.boot.autoconfigure.jdbc.metadata.DataSourcePoolMetadataProvidersConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.boot.jdbc.EmbeddedDatabaseConnection;
import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.ConfigurationCondition.ConfigurationPhase;
import org.springframework.core.type.AnnotatedTypeMetadata;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;@Configuration(proxyBeanMethods = false
)
@ConditionalOnClass({DataSource.class, EmbeddedDatabaseType.class})
@EnableConfigurationProperties({DataSourceProperties.class})
@Import({DataSourcePoolMetadataProvidersConfiguration.class, DataSourceInitializationConfiguration.class})
public class DataSourceAutoConfiguration {public DataSourceAutoConfiguration() {}static class EmbeddedDatabaseCondition extends SpringBootCondition {private final SpringBootCondition pooledCondition = new PooledDataSourceCondition();EmbeddedDatabaseCondition() {}public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {ConditionMessage.Builder message = ConditionMessage.forCondition("EmbeddedDataSource", new Object[0]);if (this.anyMatches(context, metadata, new Condition[]{this.pooledCondition})) {return ConditionOutcome.noMatch(message.foundExactly("supported pooled data source"));} else {EmbeddedDatabaseType type = EmbeddedDatabaseConnection.get(context.getClassLoader()).getType();return type == null ? ConditionOutcome.noMatch(message.didNotFind("embedded database").atAll()) : ConditionOutcome.match(message.found("embedded database").items(new Object[]{type}));}}}static class PooledDataSourceAvailableCondition extends SpringBootCondition {PooledDataSourceAvailableCondition() {}public ConditionOutcome getMatchOutcome(ConditionContext context, AnnotatedTypeMetadata metadata) {ConditionMessage.Builder message = ConditionMessage.forCondition("PooledDataSource", new Object[0]);return DataSourceBuilder.findType(context.getClassLoader()) != null ? ConditionOutcome.match(message.foundExactly("supported DataSource")) : ConditionOutcome.noMatch(message.didNotFind("supported DataSource").atAll());}}static class PooledDataSourceCondition extends AnyNestedCondition {PooledDataSourceCondition() {super(ConfigurationPhase.PARSE_CONFIGURATION);}@Conditional({PooledDataSourceAvailableCondition.class})static class PooledDataSourceAvailable {PooledDataSourceAvailable() {}}@ConditionalOnProperty(prefix = "spring.datasource",name = {"type"})static class ExplicitType {ExplicitType() {}}}@Configuration(proxyBeanMethods = false)@Conditional({PooledDataSourceCondition.class})@ConditionalOnMissingBean({DataSource.class, XADataSource.class})@Import({DataSourceConfiguration.Hikari.class, DataSourceConfiguration.Tomcat.class, DataSourceConfiguration.Dbcp2.class, DataSourceConfiguration.Generic.class, DataSourceJmxConfiguration.class})protected static class PooledDataSourceConfiguration {protected PooledDataSourceConfiguration() {}}@Configuration(proxyBeanMethods = false)@Conditional({EmbeddedDatabaseCondition.class})@ConditionalOnMissingBean({DataSource.class, XADataSource.class})@Import({EmbeddedDataSourceConfiguration.class})protected static class EmbeddedDatabaseConfiguration {protected EmbeddedDatabaseConfiguration() {}}
}
分析@ConditionalOnClass({DataSource.class, EmbeddedDatabaseType.class})注解,
上面的类当同时存在DataSource.class和EmbeddedDatabaseType.class类才会自动导入
DataSourceAutoConfiguration,并且会通过@EnableConfigurationProperties注解读取相关的数据库的配置文件,点进DataSourceProperties该类可以看到它是一个配置类,上面有@ConfigurationProperties注解,该配置类会绑定以spring.datasource为前缀的配置数据,我们使用比较多的是在配置文件里面配置数据库的url,用户名,密码等等来和该类的做数据绑定。
接下来进入类里面,比较重要的是下面两个类的判断。
@Configuration(proxyBeanMethods = false)@Conditional({PooledDataSourceCondition.class})@ConditionalOnMissingBean({DataSource.class, XADataSource.class})@Import({DataSourceConfiguration.Hikari.class, DataSourceConfiguration.Tomcat.class, DataSourceConfiguration.Dbcp2.class, DataSourceConfiguration.Generic.class, DataSourceJmxConfiguration.class})protected static class PooledDataSourceConfiguration {protected PooledDataSourceConfiguration() {}}@Configuration(proxyBeanMethods = false)@Conditional({EmbeddedDatabaseCondition.class})@ConditionalOnMissingBean({DataSource.class, XADataSource.class})@Import({EmbeddedDataSourceConfiguration.class})protected static class EmbeddedDatabaseConfiguration {protected EmbeddedDatabaseConfiguration() {}}
1.PooledDataSourceConfiguration类上注解
1)@Conditional({PooledDataSourceCondition.class})
首先PooledDataSourceCondition.class类要存在
2)@ConditionalOnMissingBean({DataSource.class, XADataSource.class})
这两个类其中一个不存在则成立
(1)(2)两个都条件成立才注入PooledDataSourceConfiguration类
3)@Import({DataSourceConfiguration.Hikari.class, DataSourceConfiguration.Tomcat.class, DataSourceConfiguration.Dbcp2.class, DataSourceConfiguration.Generic.class, DataSourceJmxConfiguration.class})
这里面引入很多类型的数据源配置,当条件成立,PooledDataSourceConfiguration该类会去对应的数据源配置找数据。(找的都是池化类型的数据源,例如mysql的数据源)
2.EmbeddedDatabaseConfiguration类上注解
1)@Conditional({EmbeddedDatabaseCondition.class})
EmbeddedDatabaseCondition类存在为true
2)@ConditionalOnMissingBean({DataSource.class, XADataSource.class})
并且这两个类其中一个不存在则成立
(1)(2)两个条件都成立才创建EmbeddedDatabaseConfiguration类
3)@Import({EmbeddedDataSourceConfiguration.class})
导入内嵌型的数据源配置