龙空技术网

Springboot如何自动加载数据源

攻城狮Bilbo 1035

前言:

今天同学们对“springboot 动态数据源”大概比较讲究,各位老铁们都需要分析一些“springboot 动态数据源”的相关知识。那么小编在网络上收集了一些对于“springboot 动态数据源””的相关知识,希望看官们能喜欢,我们快快来了解一下吧!

Springboot应用程序中数据源(Datasource)的加载有两种方式,一是手动创建一个Datasource,二是根据properties或者yml配置文件自动加载Datasource。这里重点关注Springboot是如何自动加载Datasource的。本文Springboot的版本为2.3.5

spring-boot-autoconfigure

Springboot的自动装配依赖注解EnableAutoConfiguration,关于这个的源码分析后续再说,这里不是重点。简单说就是:如果配置了EnableAutoConfiguration注解,Springboot会扫描项目依赖包下是否包含spring.factories文件,如果包含则加载文件中配置的对应的类,这就是Springboot自己实现的SPI机制,关于SPI机制,以后再说。在Springboot应用程序中的启动类的注解@SpringBootApplication包含了EnableAutoConfiguration注解,所以会扫描依赖查找spring.factories文件。spring-boot-autoconfigure包故名思义就是负责自动配置,在这个包META-INF目录下面可以找到一个spring.factories,文件太长,我截取一部分入下:

spring.factories

配置文件中的类会被加载,这里我们重点关注DataSourceAutoConfiguration,从名字看出来,它主要负责数据源自动配置。

DataSourceAutoConfiguration

源码比较长,先看下类上的几个注解:

DataSourceAutoConfiguration

@Configuration(proxyBeanMethods = false)

@Configuration这个注解比较常见,标识了这个类可以被扫描,proxyBeanMethods这个属性用来制定这个类中被@Bean注解标注的方法是否使用代理,当为true时,直接从IOC容器之中取得对象,当为如果设置为false,也就是不使用注解,每次调用@Bean标注的方法获取到的对象和IOC容器中的都不一样,是一个新的对象。

@ConditionalOnClass({DataSource.class, EmbeddedDatabaseType.class})

这个注解表示,只有当DatasourceEmbeddedDatabaseType这两个类对应的Bean不存在时才DataSourceAutoConfiguration会被实例化到容器中。这个类本来就是要做数据源配置的,如果存在上述的两个Bean,那么说明数据源已经存在,不需要配置了。

@ConditionalOnMissingBean(type = {"io.r2dbc.spi.ConnectionFactory"})

这个朱标表示,只有不存在io.r2dbc.spi.ConnectionFactory类型的Bean时这个类才会被实例化到容器中。r2dbc是一种异步的、非阻塞的关系式数据库连接规范。也就是说只有在采用JDBC规范的情况下才会实例化这个配置类。

@EnableConfigurationProperties({DataSourceProperties.class})

这个配置会将properties或者yml中的配置映射到DataSourceProperties中,并将DataSourceProperties实例化为一个Bean。

DataSourceProperties部分源码如下:

DataSourceProperties

@ConfigurationProperties(prefix = "spring.datasource")可以将配置文件中前缀为spring.datasource的属性映射到对应的DataSourceProperties属性中。

@Import({DataSourcePoolMetadataProvidersConfiguration.class, DataSourceInitializationConfiguration.class})

DataSourceInitializationConfigurationDataSourcePoolMetadataProvidersConfiguration实例化为Bean交给IOC容器管理。

DataSourceAutoConfiguration主要实现了五个功能:1.初始化DataSourceProperties实例

将配置文件属性映射到DataSourceProperties中,这个功能上面已经介绍

2.检测并配置内置数据库,例如H2,DERBY,HSQL

这个功能具体实现源码如下:

EmbeddedDatabaseConfiguration

@Conditional({DataSourceAutoConfiguration.EmbeddedDatabaseCondition.class})这个注解比较重要,EmbeddedDatabaseCondition继承了SpringBootConditionSpringBootCondition是一个模板类,继承它后,只需要实现核心的getMatchOutCome()方法来自定义一个 Condition 类。当这个类被@Conditional 注解引入的时候,最终时候执行这个核心方法来判断是否匹配的。在这里这个注解主要用来判断是否使用内置数据库,如果使用则引入内置数据库配置类EmbeddedDataSourceConfiguration

其他几个注解上面已经涉及到,这里就不再赘述。

3.数据源配置

数据源配置相关源码如下:

PooledDataSourceConfiguration

这里的@Conditional({DataSourceAutoConfiguration.PooledDataSourceCondition.class})注解和上文类似,如果满足1.有spring.datasource.type属性 2.PooledDataSourceAvailableCondition:项目中引入了数据源依赖,这两个条件中的任意一个则按顺序解析@Import({Hikari.class, Tomcat.class, Dbcp2.class, Generic.class, DataSourceJmxConfiguration.class})中的几个类。例如导入Hikari.class,则会实例化对应的Datasource,即产生一个Datasource类型的Bean。

4. DataSourceInitializationConfiguration配置

主要负责自动运行sql文件

只要在资源路径中添加 schema.sqldata.sql 文件,springboot 在运行的时候就会自动关联数据库创建相应的表和数据。

具体由DataSourceInitializationConfiguration这个类实现,核心是其中的@Import({DataSourceInitializerInvoker.class, DataSourceInitializationConfiguration.Registrar.class})中的DataSourceInitializerInvoker,这类有一个方法afterPropertiesSet(),源码如下:

DataSourceInitializerInvoker

其中createSchema()方法负责查找并执行schema.sql脚本,initialize(initializer)方法负责查找并执行data.sql脚本。

5.DataSourcePoolMetadataProvidersConfiguration配置

主要用户获取内置数据源状态,这里不再赘述。

以上就是DataSourceAutoConfiguration配置类的主要功能,它负责了数据源的实例化,最终生成一个Datasource 类型的Bean加载到IOC容器中。

标签: #springboot 动态数据源