• 13Spring Boot整合第三方Druid数据源(自定义整合Druid)


           Spring Boot 2.x 默认使用 HikariCP 作为数据源,我们只要在项目中导入了 Spring Boot 的JDBC 场景启动器,便可以使用 HikariCP 数据源获取数据库连接,对数据库进行增删改查等操作。
           HikariCP 是目前市面上性能最好的数据源产品,但在实际的开发过程中,企业往往更青睐于另一款数据源产品:Druid,它是目前国内使用范围最广的数据源产品。
           Druid 是阿里巴巴推出的一款开源的高性能数据源产品,Druid 支持所有 JDBC 兼容的数据库,包括 Oracle、MySQL、SQL Server 和 H2 等等。Druid 不仅结合了 C3P0、DBCP 和 PROXOOL 等数据源产品的优点,同时还加入了强大的监控功能。通过 Druid 的监控功能,可以实时观察数据库连接池和 SQL 的运行情况,帮助用户及时排查出系统中存在的问题。

           Druid 不是 Spring Boot 内部提供的技术,它属于第三方技术,我们可以通过以下两种方式进行整合: 

    • 自定义整合 Druid 
    • 通过 starter 整合 Druid 

    本章只介绍 自定义整合 Druid,下一章介绍通过 starter 整合 Druid 。

    通过自定义方式 整合 Druid

           自定义整合 Druid 是指:根据 Druid 官方文档和自身的需求,通过手动创建 Druid 数据源的方式,将 Druid 整合到 Spring Boot 中。     

    1. 引入 Druid 依赖

           在项目的 pom.xml 中引入 Druid 的依赖(dependency ),即可将 Druid 导入到 Spring Boot 项目中。添加以下依赖,引入 JDBC 场景启动器、MySql 数据库驱动 和 Druid 依赖。

    1. <!--导入 JDBC 场景启动器-->
    2. <dependency>
    3. <groupId>org.springframework.boot</groupId>
    4. <artifactId>spring-boot-starter-data-jdbc</artifactId>
    5. </dependency>
    6. <!--导入数据库驱动-->
    7. <dependency>
    8. <groupId>mysql</groupId>
    9. <artifactId>mysql-connector-java</artifactId>
    10. <scope>runtime</scope>
    11. </dependency>
    12. <!--采用自定义方式整合 druid 数据源-->
    13. <!--自定义整合需要编写一个与之相关的配置类-->
    14. <dependency>
    15. <groupId>com.alibaba</groupId>
    16. <artifactId>druid</artifactId>
    17. <version>1.2.6</version>
    18. </dependency>

    2. 创建数据源

           我们知道,Spring Boot 使用 HikariCP 作为其默认数据源,当容器中没有 DataSource(数据源类)时,Spring Boot 才会使用 HikariCP 作为其默认数据源。 也就是说,若我们向容器中添加 Druid 数据源类(DruidDataSource,继承自 DataSource)的对象时,Spring Boot 就会使用 Druid 作为其数据源,而不再使用 HikariCP。如下图。

    创建数据源配置类

           可以使用配置类来创数据源,此配置类向IOC容器中添加了 Druid 数据源对象。

           我们一般不建议使用下面方式 将数据源属性硬编码到代码中:
             druidDataSource.setUrl("jdbc:mysql://127.0.0.1:3306/tyut");
             druidDataSource.setUsername("root");
             druidDataSource.setPassword("root");
             druidDataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
           建议使用注解@ConfigurationProperties配置文件进行绑定,此注解将application.yml配置文件中spring.datasource 开头的配置与数据源中的属性进行绑定。代码如下:

    1. package cn.edu.tyut.springboot.config;
    2. import com.alibaba.druid.pool.DruidDataSource;
    3. import org.springframework.boot.context.properties.ConfigurationProperties;
    4. import org.springframework.context.annotation.Bean;
    5. import org.springframework.context.annotation.Configuration;
    6. import javax.sql.DataSource;
    7. import java.sql.SQLException;
    8. @Configuration
    9. public class DataSourceConfig {
    10. /**
    11. * 使用此配置类向容器中添加了 Druid 数据源对象。
    12. *
    13. * 我们一般不建议使用下面方式 将数据源属性硬编码到代码中
    14. * druidDataSource.setUrl("jdbc:mysql://127.0.0.1:3306/tyut");
    15. * druidDataSource.setUsername("root");
    16. * druidDataSource.setPassword("root");
    17. * druidDataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
    18. * 建议使用注解@ConfigurationProperties与配置文件中进行绑定
    19. * 它将配置文件中 spring.datasource 开头的配置与数据源中的属性进行绑定
    20. *
    21. */
    22. @ConfigurationProperties("spring.datasource")
    23. @Bean
    24. public DataSource dataSource() throws SQLException {
    25. DruidDataSource druidDataSource = new DruidDataSource();
    26. return druidDataSource;
    27. }
    28. }

    配置数据源

           在配置文件 application.yml 中添加以下数据源配置,它们会与与 Druid 数据源中的属性进行绑定,代码如下。

    1. #数据源连接信息
    2. spring:
    3. datasource:
    4. username: root
    5. password: root
    6. url: jdbc:mysql://127.0.0.1:3306/bianchengbang_jdbc
    7. driver-class-name: com.mysql.cj.jdbc.Driver

    至此,我们就已经将数据源从 HikariCP 切换到了 Druid 了

     注:配置类创建 Druid 数据源对象时,应该尽量避免将数据源信息(例如 url、username 和 password 等)硬编码到代码中,而应该通过 @ConfigurationProperties("spring.datasource") 注解,将 Druid 数据源对象的属性与配置文件中的以“spring.datasource”开头的配置进行绑定。

    1. import org.junit.jupiter.api.Test;
    2. import org.springframework.beans.factory.annotation.Autowired;
    3. import org.springframework.boot.test.context.SpringBootTest;
    4. import org.springframework.jdbc.core.JdbcTemplate;
    5. import javax.sql.DataSource;
    6. import java.sql.SQLException;
    7. @SpringBootTest
    8. class TyutSpringbootApplicationTests{
    9. //数据源组件
    10. @Autowired
    11. DataSource dataSource;
    12. //用于访问数据库的组件
    13. @Autowired
    14. JdbcTemplate jdbcTemplate;
    15. @Test
    16. void contextLoads() throws SQLException {
    17. System.out.println("默认数据源为:" + dataSource.getClass());
    18. System.out.println("数据库连接实例:" + dataSource.getConnection());
    19. //访问数据库
    20. Integer i = jdbcTemplate.queryForObject("SELECT count(*) from `user`", Integer.class);
    21. System.out.println("user 表中共有" + i + "条数据。");
    22. }
    23. }

    3. 开启 Druid 内置监控页面

           Druid 内置提供了一个名为 StatViewServlet 的 Servlet,这个 Servlet 可以开启 Druid 的内置监控页面功能, 展示 Druid 的统计信息,它的主要用途如下:

    • 提供监控信息展示的 html 页面
    • 提供监控信息的 JSON API

    注意:使用 StatViewServlet,建议使用 Druid 0.2.6 以上版本。

           根据 Druid 官方文档-配置_StatViewServlet 配置,StatViewServlet 是一个标准的 javax.servlet.http.HttpServlet,想要开启 Druid 的内置监控页面,需要将该 Servlet 配置在 Web 应用中的 WEB-INF/web.xml 中,web.xml 中配置如下。

    1. <servlet>
    2. <servlet-name>DruidStatViewservlet-name>
    3. <servlet-class>com.alibaba.druid.support.http.StatViewServletservlet-class>
    4. servlet>
    5. <servlet-mapping>
    6. <servlet-name>DruidStatViewservlet-name>
    7. <url-pattern>/druid/*url-pattern>
    8. servlet-mapping>

             但Spring Boot 项目中是没有 WEB-INF/web.xml 的,因此我们可以 自定义一个类继承StatViewServlet,在自定义的类上使用注解,且在启动类上使用@ServletComponentScan。(不推荐)

    1. 自定义类
    2. package cn.edu.tyut.springboot.config;
    3. import com.alibaba.druid.support.http.StatViewServlet;
    4. import javax.servlet.annotation.WebServlet;
    5. @WebServlet(name = "myDruidStatView", urlPatterns = "/durid/*")
    6. public class MyDruidStatView extends StatViewServlet {
    7. }
    8. 启动类
    9. @ServletComponentScan
    10. @SpringBootTest
    11. class TyutSpringbootApplicationTests {

    推荐方式:我们可以在自定义配置类DataSourceConfig中,通过 ServletRegistrationBean 将 StatViewServlet 注册到容器中,来开启 Druid 的内置监控页面。

    1. package cn.edu.tyut.springboot.config;
    2. import com.alibaba.druid.pool.DruidDataSource;
    3. import com.alibaba.druid.support.http.StatViewServlet;
    4. import org.springframework.boot.context.properties.ConfigurationProperties;
    5. import org.springframework.boot.web.servlet.ServletRegistrationBean;
    6. import org.springframework.context.annotation.Bean;
    7. import org.springframework.context.annotation.Configuration;
    8. import javax.sql.DataSource;
    9. import java.sql.SQLException;
    10. @Configuration
    11. public class DataSourceConfig {
    12. /**
    13. * 使用此配置类向容器中添加了 Druid 数据源对象。
    14. *
    15. * 我们一般不建议使用下面方式 将数据源属性硬编码到代码中
    16. * druidDataSource.setUrl("jdbc:mysql://127.0.0.1:3306/tyut");
    17. * druidDataSource.setUsername("root");
    18. * druidDataSource.setPassword("root");
    19. * druidDataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
    20. * 建议使用注解@ConfigurationProperties与配置文件中进行绑定
    21. * 它将配置文件中 spring.datasource 开头的配置与数据源中的属性进行绑定
    22. *
    23. */
    24. @ConfigurationProperties("spring.datasource")
    25. @Bean
    26. public DataSource dataSource() throws SQLException {
    27. DruidDataSource druidDataSource = new DruidDataSource();
    28. return druidDataSource;
    29. }
    30. /**
    31. * 开启 Druid 数据源内置监控页面
    32. *
    33. * @return
    34. */
    35. @Bean
    36. public ServletRegistrationBean statViewServlet() {
    37. StatViewServlet statViewServlet = new StatViewServlet();
    38. //向容器中注入 StatViewServlet,并将其路径映射设置为 /druid/*
    39. ServletRegistrationBean servletRegistrationBean = new ServletRegistrationBean(statViewServlet, "/druid/*");
    40. //配置监控页面访问的账号和密码(选配)
    41. servletRegistrationBean.addInitParameter("loginUsername", "admin");
    42. servletRegistrationBean.addInitParameter("loginPassword", "123456");
    43. return servletRegistrationBean;
    44. }
    45. }

           启动 Spring Boot,浏览器访问“http://localhost:8080/druid”,即可访问 Druid 的内置监控页面的登陆页,结果如下。

           在登陆页输入框内,分别输入自定义的用户名(loginUsername)和密码(loginPassword),如下图。 

    4. 开启 SQL 监控

           Druid 内置提供了一个 StatFilter,通过它可以开启 Druid 的 SQL 监控功能,对 SQL 进行监控。StatFilter 的别名是 stat,这个别名的映射配置信息保存在 druid-xxx.jar!/META-INF/druid-filter.properties 中。Druid 官方文档-配置_StatFilter 中给出了在 Spring 中配置该别名(stat)开启 Druid SQL 监控的方式,配置如下。

    1. <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
    2. ... ...
    3. <property name="filters" value="stat" />
    4. bean>

           根据以上配置我们可以看出,只要自定义配置类DataSourceConfig中 dataSource 的 Bean 中添加一个取值为“stat”的“filters”属性,就能开启 Druid SQL 监控,因此我们只要将该配置转换为在配置类中进行即可,代码如下。

    1. @ConfigurationProperties("spring.datasource")
    2. @Bean
    3. public DataSource dataSource() throws SQLException {
    4. DruidDataSource druidDataSource = new DruidDataSource();
    5. //设置 filters 属性值为 stat,开启 SQL 监控
    6. druidDataSource.setFilters("stat");
    7. return druidDataSource;
    8. }

           执行下面代码进行测试,并访问 Druid 的内置监控页面,切换到 SQL 监控模块,可以看到 Druid SQL 监控已经开启。

    1. import org.junit.jupiter.api.Test;
    2. import org.springframework.beans.factory.annotation.Autowired;
    3. import org.springframework.boot.test.context.SpringBootTest;
    4. import org.springframework.jdbc.core.JdbcTemplate;
    5. import javax.sql.DataSource;
    6. import java.sql.SQLException;
    7. @SpringBootTest
    8. class TyutSpringbootApplicationTests{
    9. //数据源组件
    10. @Autowired
    11. DataSource dataSource;
    12. //用于访问数据库的组件
    13. @Autowired
    14. JdbcTemplate jdbcTemplate;
    15. @Test
    16. void contextLoads() throws SQLException {
    17. System.out.println("默认数据源为:" + dataSource.getClass());
    18. System.out.println("数据库连接实例:" + dataSource.getConnection());
    19. //访问数据库
    20. Integer i = jdbcTemplate.queryForObject("SELECT count(*) from `user`", Integer.class);
    21. System.out.println("user 表中共有" + i + "条数据。");
    22. }
    23. }

    5. 开启防火墙

           Druid 内置提供了一个 WallFilter,使用它可以开启防火墙功能,防御 SQL 注入攻击。
    WallFilter 的别名是 wall,这个别名映射配置信息保存在 druid-xxx.jar!/META-INF/druid-filter.properties 中。Druid 官方文档-配置 wallfilter 中给出了在 Spring 中使用该别名(wall)开启防火墙的方式,配置如下。

    1. <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
    2. ... ...
    3. <property name="filters" value="wall" />
    4. bean>

    WallFilter 可以结合其他 Filter 一起使用,例如:

    1. <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
    2. ...
    3. <property name="filters" value="wall,stat"/>
    4. bean>

    根据以上配置我们可以看出,只要在 dataSource 的 Bean 中添加一个取值为“wall”的“filters”属性,就能开启 Druid 的防火墙功能,因此我们只需要在配置类中为 dataSource 的 filters 属性再添加一个“wall”即可(多个属性值之间使用逗号“,”隔开),代码如下。

    1. @ConfigurationProperties("spring.datasource")
    2. @Bean
    3. public DataSource dataSource() throws SQLException {
    4. DruidDataSource druidDataSource = new DruidDataSource();
    5. //同时开启 sql 监控(stat) 和防火墙(wall),中间用逗号隔开。
    6. //开启防火墙能够防御 SQL 注入攻击
    7. druidDataSource.setFilters("stat,wall");
    8. return druidDataSource;
    9. }

         执行下面代码进行测试,并访问 Druid 的内置监控页面,切换到 SQL 监控模块,可以看到 Druid SQL 监控已经开启。

    1. import org.junit.jupiter.api.Test;
    2. import org.springframework.beans.factory.annotation.Autowired;
    3. import org.springframework.boot.test.context.SpringBootTest;
    4. import org.springframework.jdbc.core.JdbcTemplate;
    5. import javax.sql.DataSource;
    6. import java.sql.SQLException;
    7. @SpringBootTest
    8. class TyutSpringbootApplicationTests{
    9. //数据源组件
    10. @Autowired
    11. DataSource dataSource;
    12. //用于访问数据库的组件
    13. @Autowired
    14. JdbcTemplate jdbcTemplate;
    15. @Test
    16. void contextLoads() throws SQLException {
    17. System.out.println("默认数据源为:" + dataSource.getClass());
    18. System.out.println("数据库连接实例:" + dataSource.getConnection());
    19. //访问数据库
    20. Integer i = jdbcTemplate.queryForObject("SELECT count(*) from `user`", Integer.class);
    21. System.out.println("user 表中共有" + i + "条数据。");
    22. }
    23. }

    6. 开启 Web-JDBC 关联监控

    Druid 还内置提供了一个名为 WebStatFilter 的过滤器,它可以用来监控与采集 web-jdbc 关联监控的数据。

    根据 Druid 官方文档-配置_配置WebStatFilter,想要开启 Druid 的 Web-JDBC 关联监控,只需要将 WebStatFilter 配置在 Web 应用中的 WEB-INF/web.xml 中即可,web.xml 配置如下。

    1. <filter>
    2. <filter-name>DruidWebStatFilterfilter-name>
    3. <filter-class>com.alibaba.druid.support.http.WebStatFilterfilter-class>
    4. <init-param>
    5. <param-name>exclusionsparam-name>
    6. <param-value>*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*param-value>
    7. init-param>
    8. filter>
    9. <filter-mapping>
    10. <filter-name>DruidWebStatFilterfilter-name>
    11. <url-pattern>/*url-pattern>
    12. filter-mapping>

    Spring Boot 项目中是没有 WEB-INF/web.xml 的,但是我们可以在配置类中,通过 FilterRegistrationBean 将 WebStatFilter 注入到容器中,来开启 Druid 的 Web-JDBC 关联监控。

    配置类中示例代码如下。

    1. /**
    2. * 向容器中添加 WebStatFilter
    3. * 开启内置监控中的 Web-jdbc 关联监控的数据
    4. * @return
    5. */
    6. @Bean
    7. public FilterRegistrationBean druidWebStatFilter() {
    8. WebStatFilter webStatFilter = new WebStatFilter();
    9. FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(webStatFilter);
    10. // 监控所有的访问
    11. filterRegistrationBean.setUrlPatterns(Arrays.asList("/*"));
    12. // 监控访问不包括以下路径
    13. filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
    14. return filterRegistrationBean;
    15. }

           执行下面代码进行测试,并访问 Druid 的内置监控页面,切换到 SQL 监控模块,可以看到 Druid SQL 监控已经开启。

    1. import org.junit.jupiter.api.Test;
    2. import org.springframework.beans.factory.annotation.Autowired;
    3. import org.springframework.boot.test.context.SpringBootTest;
    4. import org.springframework.jdbc.core.JdbcTemplate;
    5. import javax.sql.DataSource;
    6. import java.sql.SQLException;
    7. @SpringBootTest
    8. class TyutSpringbootApplicationTests{
    9. //数据源组件
    10. @Autowired
    11. DataSource dataSource;
    12. //用于访问数据库的组件
    13. @Autowired
    14. JdbcTemplate jdbcTemplate;
    15. @Test
    16. void contextLoads() throws SQLException {
    17. System.out.println("默认数据源为:" + dataSource.getClass());
    18. System.out.println("数据库连接实例:" + dataSource.getConnection());
    19. //访问数据库
    20. Integer i = jdbcTemplate.queryForObject("SELECT count(*) from `user`", Integer.class);
    21. System.out.println("user 表中共有" + i + "条数据。");
    22. }
    23. }

     与此同时,URI 监控和 Session 监控也都被开启,如下图。

     

    14Spring Boot整合第三方Druid数据源(通过starter整合 Druid )

    14Spring Boot整合第三方Druid数据源(通过starter整合 Druid )_爱吃面的猫的博客-CSDN博客

    15Spring Boot整合MyBatis

    15Spring Boot整合MyBatis_爱吃面的猫的博客-CSDN博客

  • 相关阅读:
    刷题记录:牛客NC16655[NOIP2005]过河
    Unsupervised Medical Image Translation with Adversarial Diffusion Models
    忆享科技戟星安全实验室|互联网资产搜集平台大全
    2020年五一杯数学建模A题煤炭价格预测问题解题全过程文档及程序
    react 生命周期讲解
    Ansible中的角色使用
    1.Docker简介
    【嵌入式开源库】timeslice的使用,完全解耦的时间片轮询框架构
    Maven依赖的作用域你到底用对了没有
    控制鼠标移动
  • 原文地址:https://blog.csdn.net/qq_41946216/article/details/127094538