基于springboot之druid连接池自动装配原理解析

druid

  • 1.概述
  • 2.环境配置
  • 3.springboot 自动装配浅析
    • @EnableAutoConfiguration注解
  • 4. DruidDataSourceAutoConfigure
    • 4.1 @Configuration
    • 4.2 @ConditionalOnClass(DruidDataSource.class)
    • 4.3 @AutoConfigureBefore
    • 4.4 @EnableConfigurationProperties
    • 4.5 @Import
  • 5.DataSourceBean

1.概述

因为druid会用到springboot的自动装配,对这个有基础的可以略过第3个直接进入主题
ps(错误和不足的地方欢迎大佬指正)
基于springboot之druid连接池自动装配原理解析_第1张图片

2.环境配置

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-dependencies</artifactId>
    <version>2.1.17.RELEASE</version>
</parent>
// web 依赖  基于web环境
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
// 使用JdbcTemplate 操作访问
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
// druid 依赖
<dependency>
     <groupId>com.alibaba</groupId>
     <artifactId>druid-spring-boot-starter</artifactId>
     <version>1.1.14</version>
 </dependency>
 // mysql驱动包
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>
// application.yml 配置
 spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driverClassName: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
    username: 
    password: 
    druid:
      stat-view-servlet:
        enabled: true
        # 设置白名单,不填则允许所有访问
        allow: 127.0.0.1
        url-pattern: /druid/*
        # 控制台管理用户名和密码
        login-username: admin
        login-password: 123456
      web-stat-filter:
        enabled: true
      filter:
        stat:
          enabled: true
          # 慢SQL记录
          log-slow-sql: true
          slow-sql-millis: 1000
          merge-sql: true
        wall:
          config:
            multi-statement-allow: true

3.springboot 自动装配浅析

@EnableAutoConfiguration注解

第一步:点进去老铁,不要怕,奥里给!
基于springboot之druid连接池自动装配原理解析_第2张图片
发现其中里面有一个开启自动配置的注解,继续点进去
基于springboot之druid连接池自动装配原理解析_第3张图片
好了,点到为止,@Import注解直接导入了一个ImportSelector的实现类,此时肯定有人会问,这个ImportSelector又是什么鬼捏,先声明一下,这个ImportSelector是spring的扩展点之一,铁子们继续往下看
基于springboot之druid连接池自动装配原理解析_第4张图片
在这里插入图片描述
在这里插入图片描述
这里是springboot启动之后会执行ConfigurationClassPostProcessor后置处理器的postProcessBeanDefinitionRegistry方法,因为它实现了BeanDefinitionRegistryPostProcessor接口,在spring声明周期里会执行,现在先不管什么时候执行的,后面有时间再写一个spring的,然后往下一步一步走,就到了解析import注解的地方,仔细瞅着铁子们,找到selectImports 方法
基于springboot之druid连接池自动装配原理解析_第5张图片
如果自定义的实现了DeferredImportSelector 表示推迟选中,会放入group里面依次取出然后再将执行selector.selectImports(metadata)返回的全限定名称作为配置类依次扫描加载注册
基于springboot之druid连接池自动装配原理解析_第6张图片
这个时候铁子们肯定会问,看这个搞什么鬼,别急别急,铁子们精彩继续!
回到AutoConfigurationImportSelector 找到selectImports方法进入getAutoConfigurationEntry
基于springboot之druid连接池自动装配原理解析_第7张图片
基于springboot之druid连接池自动装配原理解析_第8张图片
继续getCandidateConfigurations
基于springboot之druid连接池自动装配原理解析_第9张图片
基于springboot之druid连接池自动装配原理解析_第10张图片
在这里插入图片描述
基于springboot之druid连接池自动装配原理解析_第11张图片
基于springboot之druid连接池自动装配原理解析_第12张图片
终于快结束了,看到没有spring会默认加载class目录下面的META-INF/spring.factories文件的配置类
基于springboot之druid连接池自动装配原理解析_第13张图片
基于springboot之druid连接池自动装配原理解析_第14张图片
好,铁子们激动不激动,现在找到druid的starter这个配置文件 发现里面有一个正是我们要找的DruidDataSourceAutoConfigure,我想这个时候大家应该能自己手写一个springboot的starter了吧,嘻嘻
在这里插入图片描述
基于springboot之druid连接池自动装配原理解析_第15张图片

4. DruidDataSourceAutoConfigure

下面对这个类上的注解依次解析

4.1 @Configuration

这个注解不要问 直接过

4.2 @ConditionalOnClass(DruidDataSource.class)

这个表示是否存在DruidDataSource类 存在才会加载DruidDataSourceAutoConfigure配置类,这里肯定存在啦

4.3 @AutoConfigureBefore

@AutoConfigureBefore表示在DataSourceAutoConfiguration类之前加载DruidDataSourceAutoConfigure配置类,为什么捏,大家可以在springboot的autoconfigure的META-INF/spring.factories里面找到EnableAutoConfiguration下的JdbcTemplateAutoConfiguration和DataSourceAutoConfiguration,这两个类是spring默认加载装配的一个类,JdbcTemplateAutoConfiguration里面有一个@AutoConfigureAfter(DataSourceAutoConfiguration.class),
这个AutoConfigureAfter表示JdbcTemplateAutoConfiguration要在DataSourceAutoConfiguration类后面再加载,这样就造成一个加载的顺序:
DruidDataSourceAutoConfigure->DataSourceAutoConfiguration->JdbcTemplateAutoConfiguration,
此时细心的同学肯定会发现,在JdbcTemplateAutoConfiguration类上有一@ConditionalOnSingleCandidate(DataSource.class)注解,这个注解表示只要存在一个主的DataSource,此类才会被加载,因为JdbcTemplate需要数据源,什么是主的DataSource呢?
就是如果已经注入了一个DataSource或者注入了一个加了@Primary注解的DataSource,那么JdbcTemplateAutoConfiguration就会被加载,那为什么DruidDataSourceAutoConfigure要在DataSourceAutoConfiguration之前进行加载呢,聪明的铁子们肯定想到啦,我们来到DataSourceAutoConfiguration类里面看到基于springboot之druid连接池自动装配原理解析_第16张图片
基于springboot之druid连接池自动装配原理解析_第17张图片

@ConditionalOnMissingBean({ DataSource.class, XADataSource.class }) 表示如果存在数据源就不会被加载,相应Import里面默认的连接池就不会被spring加载,这样就避免了数据源的冲突,这个时候可能就会有人问了,不是可以配置多数据源吗?对的,可以,这个只是springboot将自己的数据源关闭掉,并不会影响你自定义的

4.4 @EnableConfigurationProperties

DruidStatProperties 和监控有关
DataSourceProperties:数据源的属性配置(spring.datasource)

4.5 @Import

同样和监控有关
@Import({DruidSpringAopConfiguration.class,
DruidStatViewServletConfiguration.class,
DruidWebStatFilterConfiguration.class,
DruidFilterConfiguration.class})
监控的东西可以在配置文件开启,使用
基于springboot之druid连接池自动装配原理解析_第18张图片
在这里插入图片描述

5.DataSourceBean

DruidDataSourceWrapper:使用Wrapper对数据源进行了包装,并且在创建Bean之后执行了init方法,先进入DruidDataSourceWrapper
基于springboot之druid连接池自动装配原理解析_第19张图片
@ConfigurationProperties(“spring.datasource.druid”):注入了druid的配置并且实现了spring的InitializingBean的afterPropertiesSet方法,
也就是说在bean的生命周期执行过程中执行了afterPropertiesSet 此时private DataSourceProperties basicProperties;这个已经被注入,
super.setUsername(basicProperties.determineUsername());表示你如果没有spring.datasource.druid.username而配置了spring.datasource.username
那么就会读取spring.datasource.username的属性值,至于init方法去它的父类肯定能找到,至此,DruidDataSource 创建完成
基于springboot之druid连接池自动装配原理解析_第20张图片
我们再来看一下JdbcTemplateAutoConfiguration,通过JdbcTemplateConfiguration创建了JdbcTemplate
,DataSource被JdbcTemplate所持有,而NamedParameterJdbcOperations持有JdbcTemplate,在JdbcTemplate进行了扩展,支持命名参数特性基于springboot之druid连接池自动装配原理解析_第21张图片
基于springboot之druid连接池自动装配原理解析_第22张图片
小明收尾~耗子尾汁
基于springboot之druid连接池自动装配原理解析_第23张图片
基于springboot之druid连接池自动装配原理解析_第24张图片
基于springboot之druid连接池自动装配原理解析_第25张图片

你可能感兴趣的:(springboot,spring,java,spring,boot)