程序员码农 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)protectedstaticclassEmbeddedDatabaseConfiguration{}@Conditional使用了DataSourceAutoConfiguration的内部类EmbeddedDatabaseCondition来进行条件断EmbeddedDatabaseCondition主要用来检测何时可以使用内嵌DataSource , 如果已经存在池化(pooled)的DataSource,该类则不会被实例化 , 优先选择池化Data-Source 。
staticclassEmbeddedDatabaseConditionextendsSpringBootCondition{privatefinalSpringBootConditionpooledCondition=newPooledDataSource-Condition();@OverridepublicConditionOutcomegetMatchOutcome(ConditionContextcontext,Anno-tatedTypeMetadatametadata){ConditionMessage.Buildermessage=ConditionMessage.forCondition("Emb-eddedDataSource");//是否支持池化的数据源 , 支持则返回不匹配if(anyMatches(context,metadata,this.pooledCondition)){retu~nConditionOutcome.noMatch(message.foundExactly("supportedpooleddatasource"));//基于枚举类EmbeddedDatabaseType,通过类加裁器获得嵌入的数据库连接信息EmbeddedDatabaseTypetype=EmbeddedDatabaseConnection.get(context.get-ClassLoader()).getType();if(type==null){returnConditionOutcome.noMatch(message.didNotFind("embeddeddatabase").atAll());//如果枚举类中存在 , 则返回匹配returnConditionOutcome.match(message.found("embeddeddatabase").items(type));}}在EmbeddedDatabaseCondition中首先看其属性SpringBootCondition的初始化 , 首先创建了一个PooledDataSourceCondition , 该类同样是DataSourceAutoConfiguration的内部类 , 继承自AnyNestedCondition 。
AnyNestedCondition主要用于内嵌类的条件匹配场景 。
PooledDataSourceCondition类的主要作用是检查是否设置了spring.datasource.type或DataSourceAutoConfiguration.PooledDataSourceAvailableCondition , 下面为该类的源代码 。
staticclassPooledDataSourceConditionextendsAnyNestedCondition{PooledDataSourceCondition(){//没置condition的配置阶段//@Configuration注解的类解析阶段判断Condition//如果Condition不匹配 , @Configuration注解的类不会加裁super(ConfigurationPhase.PARSE__CONFIGURATION);//spring.datasource.type配置条件判断@ConditionalOnProperty(prefix="spring.datasource",name="type")staticclassExplicitType{/内部类PooledDataSourceAvailableCondition作为条件判断@Conditional(PooledDataSourceAvailableCondition.class)staticclassPooledDataSourceAvailable{PooledDataSourceCondition的构造方法中调用父类构造方法并传递枚举类Configuration-Phase的PARSE_CONFIGURATION值 , 表示被@Configuration注解的类在解析阶段的判断条件 , 如果Condition不匹配 , 则@Configuration注解的类不会加载 。 其中PooledDataSourceAvailable类的注解又用到了PooledDataSourceAvailableCondi-tion同样为DataSourceAutoConfiguration的内部类 。 staticclassPooledDataSourceAvailableConditionextendsSpringBootCondition@OverridepublicConditionOutcomegetMatchOutcome(ConditionContextcontext,Annotated-TypeMetadatametadata){ConditionMessage.Buildermessage=ConditionMessage.forCondition("PooledDataSource");//检查指定的类加裁器中是否存在默认指定的数据源 , 存在则返回匹配if(DataSourceBuilder.findType(context.getClassLoader())!=null)returnConditionOutcome.match(message.foundExactly(”supportedDataSource"));returnConditionOutcome.noMatch(message.didNotFind("supportedDataSource").}}PooledDataSourceAvailableCondition的判断逻辑非常简单 , 就是检查当前类加载器中是否存在指定的数据源对象 。 在判断的过程中使用到了DataSourceBuilder的findType方法 。