SpringBoot

您所在的位置:网站首页 springboot的底层 SpringBoot

SpringBoot

2023-12-08 22:28| 来源: 网络整理| 查看: 265

SpringBoot-11-JDBC

  SpringData简介

对于数据访问层,无论是 SQL(关系型数据库) 还是 NOSQL(非关系型数据库),Spring Boot 底层都是采用 Spring Data 的方式进行统一处理。

Spring Data 官网 查看数据库相关的启动器 :官方文档

整合JDBC

1.创建一个新项目:springboot-04-jdbc,引入相应的模块

在这里插入图片描述 2.项目搭建好后,查看spring Boot给我们导入的场景启动器和依赖

在这里插入图片描述 3.在全局(appication.yaml)配置文件编写数据源

#数据源连接信息 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/test?useSSL=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC username: root password: root 测试 @SpringBootTest class Springboot04JdbcApplicationTests { //自动装配数据源 @Autowired DataSource dataSource; @Test void contextLoads() throws SQLException { //查看数据源 System.out.println(dataSource.getClass()); //获得连接 Connection connection = dataSource.getConnection(); System.out.println(connection); //关闭连接 connection.close(); } }

运行结果 在这里插入图片描述 Spring Boot 默认使用 HikariCP 作为其数据源,对数据库的访问。

可以通过修改配置文件来修改数据源

实现如下:

spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/test?useSSL=true&useUnicode=true&characterEncoding=utf-8&serverTimezone=UTC username: root password: root # 修改默认数据源 type: org.springframework.jdbc.datasource.DriverManagerDataSource

运行结果

在这里插入图片描述

Spring Boot版本2.2.5默认使用HikariDataSource作为数据源,而以前版本 如Spring Boot版本1.5默认使用 org.apache.tomcat.jdbc.pool.DataSource 作为数据源。

HikariDataSource 号称 Java WEB 当前速度最快的数据源,相比于传统的 C3P0 、DBCP、Tomcat jdbc 等连接池更加优秀;

可以spring.datasource.type 指定自定义的数据源类型,值为 要使用的连接池实现的完全限定名。

分析原理

SpringBoot 几乎所有的默认配置都是通过配置类XxxAutoConfiguration进行配置,Spring Boot 的数据源也不例外,它的自动配置类是DataSourceAutoConfiguration

在/META-INF/spring.factories文件找到DataSourceAutoConfiguration配置类

在这里插入图片描述 EmbeddedDataSourceConfiguration 向容器中添加了一个 Spring Boot 内嵌的数据源,该数据源支持 HSQL,H2 和 DERBY 三种数据库

在这里插入图片描述

DataSourceAutoConfiguration共包括5个内部配置类

EmbeddedDatabaseConditionPooledDataSourceAvailableConditionPooledDataSourceConfigurationPooledDataSourceConfiguration(池化数据源自动配置类)EmbeddedDatabaseConfiguration(内嵌数据源自动配置类)

其中,PooledDataSourceConfiguration和EmbeddedDatabaseConfiguration为使用了@Configuration注解的自动配置类,其余三个为限定条件类。

EmbeddedDatabaseConfiguration

@Configuration(proxyBeanMethods = false) @Conditional(EmbeddedDatabaseCondition.class) //容器汇总没有数据源的配置类下生效 @ConditionalOnMissingBean({ DataSource.class, XADataSource.class }) @Import(EmbeddedDataSourceConfiguration.class) protected static class EmbeddedDatabaseConfiguration { }

EmbeddedDatabaseConfiguration是内嵌的数据源配置类,类中没有任何方法实现,主要的功能是通过@Import注解引入EmbeddedDataSourceConfiguration类实现的

@Import(EmbeddedDataSourceConfiguration.class)

点击EmbeddedDataSourceConfiguration

@Configuration(proxyBeanMethods = false) //开启配置属性,绑定DataSourceProperties类 @EnableConfigurationProperties(DataSourceProperties.class) public class EmbeddedDataSourceConfiguration implements BeanClassLoaderAware { private ClassLoader classLoader; @Override public void setBeanClassLoader(ClassLoader classLoader) { this.classLoader = classLoader; } //向容器中添加 Spring Boot 内嵌的数据源 @Bean(destroyMethod = "shutdown") public EmbeddedDatabase dataSource(DataSourceProperties properties) { return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseConnection.get(this.classLoader).getType()) .setName(properties.determineDatabaseName()).build(); } }

通过上面的分析,可知自动配置类 EmbeddedDatabaseConfiguration 的作用是向容器中添加一个内嵌的数据源(DataSource),但这是有条件限制的。

条件限制:

@Conditional(EmbeddedDatabaseCondition.class) protected static class EmbeddedDatabaseConfiguration { }

EmbeddedDatabaseConfiguration类上使用一个@Conditional注解,该注解使用了 DataSourceAutoConfiguration 的内部限制条件类 EmbeddedDatabaseCondition 来进行条件判断。

说明:

EmbeddedDatabaseCondition主要用来检测容器中是否已经存在池化数据源(PoolDataSource)。若容器中存在池化数据源时,则EmbeddedDatabaseConfiguration不能被实例化。只有当容器不存在池化数据源时,EmbeddedDatabaseConfiguraion才能被实例化,才能向容器中添加内嵌数据源(EmbeddedDataSource)

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)); }

PooledDataSourceConfiguration

@Configuration(proxyBeanMethods = false) @Conditional(PooledDataSourceCondition.class) @ConditionalOnMissingBean({ DataSource.class, XADataSource.class }) @Import({ DataSourceConfiguration.Hikari.class, DataSourceConfiguration.Tomcat.class, DataSourceConfiguration.Dbcp2.class, DataSourceConfiguration.OracleUcp.class, DataSourceConfiguration.Generic.class, DataSourceJmxConfiguration.class }) protected static class PooledDataSourceConfiguration { }

PooledDataSourceConfiguration 是池化数据源的自动配置类,通过@Conditional注解可知,该注解使用DataSourceAutoConfiguration的内部限制条件类PooledDataSourceCondition来进行条件判断。

PooledDataSourceCondition 与 EmbeddedDatabaseCondition 一样,也是用来检测容器中是否已经存在池化数据源的,但不同的是,PooledDataSourcceConfiguraion只有当容器存在池化数据源时,才可以被实例化,才可以向容器中添加池化数据源。

与 EmbeddedDatabaseConfiguration 一样,PooledDataSourceConfiguration 类中也没有任何的方法实现,它的所有功能都是通过 @Import 注解引入其他的类实现的。

PooledDataSourceConfiguration 通过 @Import 注解引入了 Hikari、Tomcat、Dbcp2、OracleUcp 和 Generic 五个数据源配置类,它们都是 DataSourceConfiguration 的内部类,且它们的功能类似,都是向容器中添加指定的数据源。

在这里插入图片描述

以 Hikari 为例进行分析

@Configuration(proxyBeanMethods = false) //表示这是一个配置类 @ConditionalOnClass(HikariDataSource.class) //表示必须类路径下存在HikariDataSource类,这个配置类才会被实例化 //HikariDataSource 类是由 spring- boot-starter-jdbc 默认将其引入的,因此只要我们在 pom.xml 中引入了该 starter, Hikari 就会被实例化 @ConditionalOnMissingBean(DataSource.class) //容器中没有DataSource这个类,才会被实例化 @ConditionalOnProperty(name = "spring.datasource.type", havingValue = "com.zaxxer.hikari.HikariDataSource", matchIfMissing = true) //Spring Boot配置文件时,配置了spring.datasource.type=com.zaxxer.hikari.HikariDataSource或者不配置spring.datasource.tyoe时,Hikari才会被实例化 static class Hikari { @Bean // 与配置文件名为spring.datasource.hikari下的所有属性绑定 @ConfigurationProperties(prefix = "spring.datasource.hikari") HikariDataSource dataSource(DataSourceProperties properties) { HikariDataSource dataSource = createDataSource(properties, HikariDataSource.class); if (StringUtils.hasText(properties.getName())) { dataSource.setPoolName(properties.getName()); } return dataSource; } }

Hikari类通过@Bean注解向容器中添加了HikariDataSource组件,该组件的实例对象是通过调用DataSourceConfiguration的createDataSource()方法得到的

createDataSource()

protected static T createDataSource(DataSourceProperties properties, Class type) { return (T) properties.initializeDataSourceBuilder().type(type).build(); }

DataSourceProperties类

在这里插入图片描述 可以知道,DataSourceProperties和我们之前在全局配置下的spring.datasource的所有属性一一对应绑定在一起,DataSourceProperties里面包含数据库的连接数据库和释放数据库等操作/.

调用了DataSourceProperties的initializeDataSourceBuilder()初始化DataSourceBuilder

initializeDataSourceBuilder()

public DataSourceBuilder initializeDataSourceBuilder() { return DataSourceBuilder.create(getClassLoader()).type(getType()).driverClassName(determineDriverClassName()) .url(determineUrl()).username(determineUsername()).password(determinePassword()); }

initialDataSourceBuilder()方法通过调用DataSourceBulider的create()方法,将application.properties/yaml的配置,依次设置数据源类型、驱动类名、连接 url、 用户名和密码等信息。

sprIng.datasource.type默认是不用配置的。createDataSource() 方法在获取到回传回来的 DataSourceBuilder 对象后,还需要将其 type 属性再次设置为 HikariDataSourcee,并调用 DataSourceBuilder 的 build() 方法,完成 HikariDataSource 的初始化。

protected static T createDataSource(DataSourceProperties properties, Class type) { return (T) properties.initializeDataSourceBuilder().type(type).build(); }

dataSource() 方法获得数据源对象,并设置了连接池的名字(name),注入到容器中。 在这里插入图片描述

总结:

用户没有配置数据源的情况,若容器中存在 HikariDataSource 类,则 Spring Boot 就会自动实例化 Hikari,并将其作为其数据源。Spring Boot 的 JDBC 场景启动器(spring-boot-starter-data-jdbc)通过 spring- boot-starter-jdbc 默认引入了 HikariCP 数据源(包含 HikariDataSource 类),因此 Spring Boot 默认使用 HikariCP 作为其数据源。


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3