SpringBoot数据库配置源码解析:自动配置内部实现解析

自动配置内部实现解析上节我们了解了 DataSourceAutoConfiguration 自动配置的注解部分 , 本节继续深入讲解该类中的内部实现 。
DataSourceAutoConfiguration中共有5个静态内 部 类, 包括EmbeddedDatabaseConfiguration 和 PooledDataSourceConfiguration 两 个 声 明 有@Configuration 注解的自动配置类 , 以及另外 3 个限制条件类:
PooledDataSourceCondition、PooledDataSourceAvailableCondition、Em-beddedDatabaseCondition 。
下面 , 将对以上涉及内容进行详解 。
EmbeddedDatabaseConfiguration
首先我们来看内部类 EmbeddedDatabaseConfiguration,该类其实并没有方法实现 , 它的主要功能是通过@Import 引入类来完成 , 源代码如下 。
@Configuration(proxyBeanMethods = false)@Conditional( EmbeddedDatabaseCondition. class)@ConditionalOnMissingBean({ DataSource. class, XADataSource. class })@Import ( EmbeddedDataSourceConfiguration. class)protected static class EmbeddedDatabaseConfiguration {}@Conditional使用了DataSourceAutoConfiguration的内部类EmbeddedDatabaseCondition 来进行条件断 EmbeddedDatabaseCondition 主要用来检测何时可以使用内嵌 DataSource , 如果已经存在池化(pooled) 的 DataSource, 该类则不会被实例化 , 优先选择池化 Data-Source 。
static class EmbeddedDatabaseCondition extends Spr ingBootCondition {private final SpringBootCondition pooledCondition = new PooledDataSource-Condition();@Overridepublic ConditionOutcome ge tMatchOutcome (ConditionContext context, Anno-tatedTypeMetadata metadata) {ConditionMessage . Builder message = ConditionMessage . forCondition("Emb-eddedDataSource");//是否支持池化的数据源 , 支 持则返回不匹配if (anyMatches(context, metadata, this. pooledCondition)) {retu~n Condit ionOutcome . noMatch(message . foundExactly(" supportedpooled data source"));//基于枚举类 EmbeddedDatabaseType,通过类加裁器获得嵌入的数据库连接信息EmbeddedDatabaseType type = EmbeddedDatabaseConnection. get(context. get-ClassLoader()). getType();if (type == null) {return ConditionOutcome . noMatch(message . didNotF ind(" embedded database").atAll());//如果枚举类中存在 , 则返回匹配return Condit ionOutcome . match(message . found(" embedded database") . items(type));}}在 EmbeddedDatabaseCondition 中首先看其属性 SpringBootCondition 的初始化 , 首先创建了一个 PooledDataSourceCondition , 该类同样是 DataSourceAutoConfiguration 的内部类 , 继承自 AnyNestedCondition 。
AnyNestedCondition 主要用于内嵌类的条件匹配场景 。
PooledDataSourceCondition 类的主要作用是检查是否设置了 spring.datasource.type 或DataSourceAutoConfiguration.PooledDataSourceAvailableCondition , 下 面为该类的源代码 。
static class PooledDataSourceCondition extends AnyNestedCondition {PooledDataSourceCondition() {//没置 condition 的配置阶段// @Configurat ion 注解的类解析阶段判断 Condition//如果 Condition 不匹配 , @Configurat ion 注解的类不会加裁 super(ConfigurationPhase .PARSE_ _CONF IGURATION);// spring. datasource. type 配置条件判断@ConditionalOnProperty(prefix = "spring . datasource", name = "type")static class ExplicitType {/内部类 PooledDataSourceAvailableCondition 作为条件判断@Conditional(PooledDataSourceAvailableCondition. class)static class PooledDataSourceAvailable {PooledDataSourceCondition 的构造方法中调用父类构造方法并传递枚举类 Configuration-Phase 的 PARSE_ CONFIGURATION 值 , 表示被@Configuration 注解的类在解析阶段的判断条件 , 如果 Condition 不匹配 ,则@Configuration 注解的类不会加载 。 其中PooledDataSourceAvailable类的注解又用到了PooledDataSourceAvailableCondi-tion 同样为 DataSourceAutoConfiguration 的内部类 。 static class PooledDataSourceAvailableCondition extends SpringBootCondition@Overridepublic ConditionOutcome getMatchOutcome(ConditionContext context, Annotated-TypeMetadata 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").}}PooledDataSourceAvailableCondition 的判断逻辑非常简单 , 就是检查当前类加载器中是否存在指定的数据源对象 。 在判断的过程中使用到了 DataSourceBuilder 的 findType 方法 。
我们看一下相关代码 ,加深理解 。
public final class DataSourceBuilder {private static final String[] DATA_ SOURCE _TYPE_ NAMES = new String[] { "com. zaxxer. hikari. HikariDataSource","org. apache . tomcat. jdbc. pool.DataSource",' org . apache. commons . dbcp2.BasicDataSource" };@SuppressWarnings("unchecked")public static Class