SpringBoot整合Druid连接池

  • 前言
  • 第一种整合方式
  • 自定义的方式
  • 引入Druid依赖
  • 配置文件
  • 配置类
  • 实现监控功能
  • 开启SQL防火墙
  • 实现web应用
  • 访问Druid页面需登录
  • 第二种整合方式
  • 引入SpringBoot的stater方式
  • 引入依赖
  • 分析自动配置
  • 具体配置示例
  • 重启服务测试
  • 总结


前言

Druid是阿里巴巴开发的数据库连接池,是目前最好的数据库连接池,在功能、性能、扩展性方面,都超过其他数据库连接池。
它包括三个部分:

  • 基于Filter-Chain模式的插件体系
  • DruidDataSource 高效可管理的数据库连接池
  • SQLParser
    Druid的功能:
  • 替换DBCP和C3P0。Druid提供了一个高效、功能强大、可扩展性好的数据库连接池
  • 可以监控数据库访问性能,Druid内置提供了一个功能强大的StatFilter插件,能够详细统计SQL的执行性能,这对于线上分析数据库访问性能有帮助
  • 数据库密码加密。直接把数据库密码写在配置文件中,这是不好的行为,容易导致安全问题。DruidDruiver和DruidDataSource都支持PasswordCallback
  • SQL执行日志,Druid提供了不同的LogFilter,能够支持Common-Logging、Log4j和JdkLog,你可以按需要选择相应的LogFilter,监控你应用的数据库访问情况
  • 扩展JDBC,如果你要对JDBC层有编程的需求,可以通过Druid提供的Filter机制,很方便编写JDBC层的扩展插件
    官方地址:
    链接: Druid官方Github地址

第一种整合方式

自定义的方式

引入Druid依赖

<dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.17</version>
        </dependency>

配置文件

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test?characterEncoding=utf8
    username: root
    password: admin
    driver-class-name: com.mysql.jdbc.Driver

配置类

配置自定义数据源

package com.gavin.boot.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
import java.sql.SQLException;

/**
 * 自定义数据源
 */
@Configuration
public class MyDataSource {

    /**
     * 配置数据源
     * @return
     */
    @ConfigurationProperties("spring.datasource")
    @Bean
    public DataSource dataSource() throws SQLException {
        DruidDataSource druidDataSource = new DruidDataSource();
        //加入监控功能
        druidDataSource.setFilters("stat,wall");
        return druidDataSource;
    }
}

测试

package com.gavin.boot;

import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import javax.sql.DataSource;

@Slf4j
@SpringBootTest
class BootJdbcApplicationTests {

    @Autowired
    DataSource dataSource;

    @Test
    void contextLoads() {
        log.info("数据源为:" + dataSource.getClass());
    }
}

测试结果为:

springboot 阿里连接池 springboot内置连接池_springboot 阿里连接池


可以看出将DataSource数据源更换为Druid数据源了,这里提一下springboot默认的数据源是Hikari

实现监控功能

先修改自定义配置类

package com.gavin.boot.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
import java.sql.SQLException;

/**
 * 自定义数据源
 */
@Configuration
public class MyDataSource {

    /**
     * 配置数据源
     * @return
     */
    @ConfigurationProperties("spring.datasource")
    @Bean
    public DataSource dataSource() throws SQLException {
        DruidDataSource druidDataSource = new DruidDataSource();
        //加入监控功能
        druidDataSource.setFilters("stat");
        return druidDataSource;
    }

    /**
     * 配置druid的监控功能
     * @return
     */
    @Bean
    public ServletRegistrationBean statViewServlet() {
        StatViewServlet statViewServlet = new StatViewServlet();
        ServletRegistrationBean<StatViewServlet> registrationBean = new ServletRegistrationBean<>(statViewServlet, "/druid/*");
        return registrationBean;
    }
}

再写一个访问数据库的controller类

package com.gavin.boot.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
public class IndexController {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @GetMapping("/sql")
    @ResponseBody
    public Long queryForObject() {
        Long aLong = jdbcTemplate.queryForObject("select count(*) from sys_user", Long.class);
        return aLong;
    }
}

重启服务测试:

先访问Druid页面

地址:http://localhost:8080/druid

springboot 阿里连接池 springboot内置连接池_springboot 阿里连接池_02


可以看出SQL监控中没有执行过SQL

接下访问IndexController 中的/sql接口,去访问数据库

地址:http://localhost:8080/sql

访问结果:

springboot 阿里连接池 springboot内置连接池_springboot 阿里连接池_03


再返回Druid页面查看SQL监控

springboot 阿里连接池 springboot内置连接池_spring boot_04


可以看出刚才访问接口的记录在SQL监控中可以看到

开启SQL防火墙

修该配置类,在druidDataSource.setFilters()方法中添加参数值wall

package com.gavin.boot.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
import java.sql.SQLException;

/**
 * 自定义数据源
 */
@Configuration
public class MyDataSource {

    /**
     * 配置数据源
     * @return
     */
    @ConfigurationProperties("spring.datasource")
    @Bean
    public DataSource dataSource() throws SQLException {
        DruidDataSource druidDataSource = new DruidDataSource();
        //加入监控功能
        druidDataSource.setFilters("stat,wall");
        return druidDataSource;
    }

    /**
     * 配置druid的监控功能
     * @return
     */
    @Bean
    public ServletRegistrationBean statViewServlet() {
        StatViewServlet statViewServlet = new StatViewServlet();
        ServletRegistrationBean<StatViewServlet> registrationBean = new ServletRegistrationBean<>(statViewServlet, "/druid/*");
        return registrationBean;
    }
}

重启服务测试:

访问/sql接口

springboot 阿里连接池 springboot内置连接池_sql_05


再访问Druid页面,点击SQL防火墙

springboot 阿里连接池 springboot内置连接池_spring_06


可以在SQL防火墙中看到刚才访问接口的信息

实现web应用

修改配置类,注入FilterRegistrationBean

package com.gavin.boot.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;
import java.sql.Array;
import java.sql.SQLException;
import java.util.Arrays;

/**
 * 自定义数据源
 */
@Configuration
public class MyDataSource {

    /**
     * 配置数据源
     * @return
     */
    @ConfigurationProperties("spring.datasource")
    @Bean
    public DataSource dataSource() throws SQLException {
        DruidDataSource druidDataSource = new DruidDataSource();
        //加入监控功能
        druidDataSource.setFilters("stat,wall");
        return druidDataSource;
    }

    /**
     * 配置druid的监控功能
     * @return
     */
    @Bean
    public ServletRegistrationBean statViewServlet() {
        StatViewServlet statViewServlet = new StatViewServlet();
        ServletRegistrationBean<StatViewServlet> registrationBean = new ServletRegistrationBean<>(statViewServlet, "/druid/*");
        return registrationBean;
    }

    /**
     * 配置WebStatFilter
     * @return
     */
    @Bean
    public FilterRegistrationBean webStatFilter() {
        WebStatFilter webStatFilter = new WebStatFilter();
        FilterRegistrationBean<WebStatFilter> registrationBean = new FilterRegistrationBean<>(webStatFilter);
        registrationBean.setUrlPatterns(Arrays.asList("/*"));
        registrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
        return registrationBean;
    }
}

重启服务测试:

访问/sql接口

springboot 阿里连接池 springboot内置连接池_java_07


再访问Druid页面,点击web应用

springboot 阿里连接池 springboot内置连接池_java_08


可以看到接口访问信息

访问Druid页面需登录

在访问Druid页面时,我们可以增加登录验证,输入正确的用户名密码后才能访问页面
实现方法:设置registrationBean.addInitParameter()和registrationBean.addInitParameter()这两个参数即可

package com.gavin.boot.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;
import java.sql.Array;
import java.sql.SQLException;
import java.util.Arrays;

/**
 * 自定义数据源
 */
@Configuration
public class MyDataSource {

    /**
     * 配置数据源
     * @return
     */
    @ConfigurationProperties("spring.datasource")
    @Bean
    public DataSource dataSource() throws SQLException {
        DruidDataSource druidDataSource = new DruidDataSource();
        //加入监控功能
        druidDataSource.setFilters("stat,wall");
        return druidDataSource;
    }

    /**
     * 配置druid的监控功能
     * @return
     */
    @Bean
    public ServletRegistrationBean statViewServlet() {
        StatViewServlet statViewServlet = new StatViewServlet();
        ServletRegistrationBean<StatViewServlet> registrationBean = new ServletRegistrationBean<>(statViewServlet, "/druid/*");
        registrationBean.addInitParameter("loginUsername", "admin");
        registrationBean.addInitParameter("loginPassword", "123456");
        return registrationBean;
    }

    /**
     * 配置WebStatFilter
     * @return
     */
    @Bean
    public FilterRegistrationBean webStatFilter() {
        WebStatFilter webStatFilter = new WebStatFilter();
        FilterRegistrationBean<WebStatFilter> registrationBean = new FilterRegistrationBean<>(webStatFilter);
        registrationBean.setUrlPatterns(Arrays.asList("/*"));
        registrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
        return registrationBean;
    }
}

重启服务测试:

直接访问Druid页面

springboot 阿里连接池 springboot内置连接池_springboot 阿里连接池_09


输入正确的用户名密码后就可以访问了

springboot 阿里连接池 springboot内置连接池_spring boot_10

第二种整合方式

引入SpringBoot的stater方式

引入依赖

<dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.1.17</version>
        </dependency>

分析自动配置

分析源码从DruidDataSourceAutoConfigure这个类作为入口,往下面去看

springboot 阿里连接池 springboot内置连接池_java_11


主要看下面这几个核心的类

springboot 阿里连接池 springboot内置连接池_java_12


简单说下这几个类的作用,有兴趣的话自己可以研究下

  • DruidSpringAopConfiguration.class:监控SpringBean
  • DruidStatViewServletConfiguration.class:监控页的配置
  • DruidWebStatFilterConfiguration.class: web监控配置
  • DruidFilterConfiguration.class:所有Druid自己filter的配置

具体配置示例

直接在application.yml配置文件里面配置就可以使用了
参考配置如下:

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/test?characterEncoding=utf8
    username: root
    password: admin
    driver-class-name: com.mysql.jdbc.Driver

    druid:
      aop-patterns: com.atguigu.admin.*  #监控SpringBean
      filters: stat,wall     # 底层开启功能,stat(sql监控),wall(防火墙)

      stat-view-servlet:   # 配置监控页功能
        enabled: true
        login-username: admin
        login-password: admin
        resetEnable: false

      web-stat-filter:  # 监控web
        enabled: true
        urlPattern: /*
        exclusions: '*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*'

      filter:
        stat:    # 对上面filters里面的stat的详细配置
          slow-sql-millis: 1000
          logSlowSql: true
          enabled: true
        wall:
          enabled: true
          config:
            drop-table-allow: false

重启服务测试

和之前一样,直接访问:http://localhost:8080/druid

springboot 阿里连接池 springboot内置连接池_spring_13


输入用户名密码登录成功后,可以访问到Druid首页

springboot 阿里连接池 springboot内置连接池_spring boot_14

总结

以上就是Druid连接池的基本用法,以后了解到其它新的功能后再更新吧。