Druid 整合 Spring Boot (一) 开始遇到的一些坑

什么是 Druid

Druid是Java语言中最好的数据库连接池。Druid能够提供强大的监控和扩展功能。

Druid Spring Boot Starter 用于帮助你在Spring Boot项目中轻松集成Druid数据库连接池和监控。

如何在Spring Boot中使用

  1. maven仓库中查询最新版本的Druid ( 如果需要使用mysql驱动则需要另作添加依赖 )

https://mvnrepository.com/artifact/com.alibaba/druid-spring-boot-starter

  • Maven
<!-- https://mvnrepository.com/artifact/com.alibaba/druid-spring-boot-starter -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.2.8</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.28</version>
</dependency>
  • Gradle
compile 'com.alibaba:druid-spring-boot-starter:1.1.17'
  1. 添加Druid配置到配置文件 (以 properties 为例)
spring.datasource.druid.url= # 或spring.datasource.url= 
spring.datasource.druid.username= # 或spring.datasource.username=
spring.datasource.druid.password= # 或spring.datasource.password=
spring.datasource.druid.driver-class-name= #或 spring.datasource.driver-class-name=

推荐配置

参考配置来源:

YML 推荐配置

server:
    port: 8080
spring:
    application:
        name: Druid
    datasource:
        type: com.alibaba.druid.pool.DruidDataSource
        druid:
            name: druid
            username: root
            password: 123456
            url: jdbc:mysql://localhost:3306/database?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
            driver-class-name: com.mysql.cj.jdbc.Driver
            # druid配置初始化时建立物理连接的个数, 最大,最小连接池数量
            initial-size: 1
            min-idle: 5
            max-active: 20
            # 获取连接时最大等待时间,单位毫秒。
            max-wait: 6000
            # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
            time-between-eviction-runs-millis: 2000
            # 配置一个连接在池中最小,最大生存的时间,单位是毫秒
            min-evictable-idle-time-millis: 600000
            max-evictable-idle-time-millis: 900000
            # 用来检测连接是否有效的sql,要求是一个查询语句
            validation-query: "select 1"

            # 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
            test-while-idle: true
            # 申请连接时执行validationQuery检测连接是否有效,开启这个配置会降低性能。
            test-on-borrow: false
            # 归还连接时执行validationQuery检测连接是否有效,开启这个配置会降低性能。
            test-on-return: false

            # 连接池中的minIdle数量以内的连接,空闲时间超过minEvictableIdleTimeMillis,则会执行keepAlive操作。
            keep-alive: true
            phy-max-use-count: 1000

            # 属性类型是字符串,通过别名的方式配置扩展插件,常用的插件有:
            # 监控统计用的filter:stat
            # 日志用的filter:log4j
            # 防御sql注入的filter:wall
            filters: stat

启动项目时会出现的一些问题

基础运行环境:

Spring Boot 2.4.5
JDK 1.8
MySQL 8.0.x

启动类

@SpringBootApplication
public class DruidApplication {
    public static void main(String[] args) {
        SpringApplication.run(DruidApplication.class, args);
    }
}

pom.xml 依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-40.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>Druid</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>Druid</name>
    <properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>2.4.5</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.alibaba/druid-spring-boot-starter -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.8</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.23</version>
        </dependency>
    </dependencies>
</project>

配置文件

spring.application.name=Druid
server.port=8080
spring.datasource.druid.url=jdbc:mysql://localhost:3306/database?useUnicode=truecharacterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
spring.datasource.druid.username=root
spring.datasource.druid.password=123456
spring.datasource.druid.driver-class-name=com.mysql.cj.jdbc.Driver

NoClassDefFoundError 类没有找到

这个时候运行会出现以下报错

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.4.5)

2022-02-14 06:12:18.182  INFO 9328 --- [           main] com.custom.system.SystemApplication      : Starting SystemApplication using Java 1.8.0_312 on DESKTOP-N8CQLV9 with PID 9328 (C:\Users\world\Desktop\git\springSecurity\target\classes started by yuan.zhang@dxc.com in C:\Users\world\Desktop\git\springSecurity)
2022-02-14 06:12:18.185  INFO 9328 --- [           main] com.custom.system.SystemApplication      : No active profile set, falling back to default profiles: default
2022-02-14 06:12:18.381 ERROR 9328 --- [           main] o.s.boot.SpringApplication               : Application run failed

java.lang.NoClassDefFoundError: org/springframework/boot/bind/RelaxedPropertyResolver
    at org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.getExcludeAutoConfigurationsProperty(AutoConfigurationImportSelector.java:215) ~[spring-boot-autoconfigure-1.5.12.RELEASE.jar:1.5.12.RELEASE]
    at org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.getExclusions(AutoConfigurationImportSelector.java:209) ~[spring-boot-autoconfigure-1.5.12.RELEASE.jar:1.5.12.RELEASE]
    at org.springframework.boot.autoconfigure.AutoConfigurationImportSelector.selectImports(AutoConfigurationImportSelector.java:99) ~[spring-boot-autoconfigure-1.5.12.RELEASE.jar:1.5.12.RELEASE]
    at org.springframework.context.annotation.ConfigurationClassParserDefaultDeferredImportSelectorGroup.process(ConfigurationClassParser.java:904) ~[spring-context-5.3.6.jar:5.3.6]
    at org.springframework.context.annotation.ConfigurationClassParserDeferredImportSelectorGrouping.getImports(ConfigurationClassParser.java:879) ~[spring-context-5.3.6.jar:5.3.6]
    at org.springframework.context.annotation.ConfigurationClassParserDeferredImportSelectorGroupingHandler.processGroupImports(ConfigurationClassParser.java:809) ~[spring-context-5.3.6.jar:5.3.6]
    at org.springframework.context.annotation.ConfigurationClassParserDeferredImportSelectorHandler.process(ConfigurationClassParser.java:780) ~[spring-context-5.3.6.jar:5.3.6]
    at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:193) ~[spring-context-5.3.6.jar:5.3.6]
    at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:331) ~[spring-context-5.3.6.jar:5.3.6]
    at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:247) ~[spring-context-5.3.6.jar:5.3.6]
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:311) ~[spring-context-5.3.6.jar:5.3.6]
    at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:112) ~[spring-context-5.3.6.jar:5.3.6]
    at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:746) ~[spring-context-5.3.6.jar:5.3.6]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:564) ~[spring-context-5.3.6.jar:5.3.6]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:144) ~[spring-boot-2.4.5.jar:2.4.5]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:782) [spring-boot-2.4.5.jar:2.4.5]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:774) [spring-boot-2.4.5.jar:2.4.5]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:439) [spring-boot-2.4.5.jar:2.4.5]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:339) [spring-boot-2.4.5.jar:2.4.5]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1340) [spring-boot-2.4.5.jar:2.4.5]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1329) [spring-boot-2.4.5.jar:2.4.5]
    at com.custom.system.SystemApplication.main(SystemApplication.java:9) [classes/:na]
Caused by: java.lang.ClassNotFoundException: org.springframework.boot.bind.RelaxedPropertyResolver
    at java.net.URLClassLoader.findClass(URLClassLoader.java:387) ~[na:1.8.0_312]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:418) ~[na:1.8.0_312]
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:352) ~[na:1.8.0_312]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:351) ~[na:1.8.0_312]
    ... 22 common frames omitted


Process finished with exit code 1

其原因在于 druid-spring-boot-starter pom里面使用的Spring Boot依赖版本是 1.5.12.RELEASE 并且引入了 spring-boot-autoconfigure , spring-jdbc, spring-boot-starter-data-jpa等, 与当前Spring Boot版本冲突了,所以没有找到类

Caused by: java.lang.ClassNotFoundException: org.springframework.boot.bind.RelaxedPropertyResolver
    at java.net.URLClassLoader.findClass(URLClassLoader.java:387) ~[na:1.8.0_312]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:418) ~[na:1.8.0_312]
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:352) ~[na:1.8.0_312]
    at java.lang.ClassLoader.loadClass(ClassLoader.java:351) ~[na:1.8.0_312]
    ... 22 common frames omitted

解决方法:

  1. (推荐) 在pom里面设置继承 spring-boot-starter-parent 版本号(此步可省略)
  2. 添加 spring-boot-autoconfigure,spring-boot-starter-jdbc 到pom中, 如果第一步省略则需要指定版本号

附录:

spring-boot-starter-data-jpa 里面包含 spring-boot-autoconfigure,spring-boot-starter-jdbc, 故可以引入jpa解决

UnsatisfiedDependencyException 无法自动装载异常

设置完成之后发现无法启动,报错信息如下

 :: Spring Boot ::                (v2.4.5)

2022-02-14 06:37:57.608  INFO 17976 --- [           main] com.custom.system.SystemApplication      : Starting SystemApplication using Java 1.8.0_312 on DESKTOP-N8CQLV9 with PID 17976 (C:\Users\world\Desktop\git\springSecurity\target\classes started by yuan.zhang@dxc.com in C:\Users\world\Desktop\git\springSecurity)
2022-02-14 06:37:57.611  INFO 17976 --- [           main] com.custom.system.SystemApplication      : No active profile set, falling back to default profiles: default
2022-02-14 06:37:58.421  INFO 17976 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8000 (http)
2022-02-14 06:37:58.432  INFO 17976 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2022-02-14 06:37:58.432  INFO 17976 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.45]
2022-02-14 06:37:58.496  INFO 17976 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2022-02-14 06:37:58.496  INFO 17976 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 848 ms
2022-02-14 06:37:58.674  INFO 17976 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2022-02-14 06:37:58.777  INFO 17976 --- [           main] c.a.d.s.b.a.DruidDataSourceAutoConfigure : Init DruidDataSource
2022-02-14 06:37:58.816  WARN 17976 --- [           main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'dataSource': Unsatisfied dependency expressed through field 'basicProperties'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'spring.datasource-org.springframework.boot.autoconfigure.jdbc.DataSourceProperties': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.autoconfigure.jdbc.DataSourceProperties]: Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseType
2022-02-14 06:37:58.816  INFO 17976 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'applicationTaskExecutor'
2022-02-14 06:37:58.818  INFO 17976 --- [           main] o.apache.catalina.core.StandardService   : Stopping service [Tomcat]
2022-02-14 06:37:58.835  INFO 17976 --- [           main] ConditionEvaluationReportLoggingListener : 

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2022-02-14 06:37:58.853 ERROR 17976 --- [           main] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'dataSource': Unsatisfied dependency expressed through field 'basicProperties'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'spring.datasource-org.springframework.boot.autoconfigure.jdbc.DataSourceProperties': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.autoconfigure.jdbc.DataSourceProperties]: Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseType
    ... 30 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'spring.datasource-org.springframework.boot.autoconfigure.jdbc.DataSourceProperties': Instantiation of bean failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.autoconfigure.jdbc.DataSourceProperties]: Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseType
    ... 21 common frames omitted
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.boot.autoconfigure.jdbc.DataSourceProperties]: Constructor threw exception; nested exception is java.lang.NoClassDefFoundError: org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseType
    ... 32 common frames omitted
Caused by: java.lang.NoClassDefFoundError: org/springframework/jdbc/datasource/embedded/EmbeddedDatabaseType
    ... 34 common frames omitted
Caused by: java.lang.ClassNotFoundException: org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType
    ... 41 common frames omitted


Process finished with exit code 1

原因&解决

出现原因同上, 只需要添加spring-boot-starter-jdbc依赖并指定 spring boot 版本即可(若使用SpringBoot版本依赖则可以不用指定)

其他

本次错误是添加了Druid依赖产生的,故我们可以查看Druid的pom文件

image.png

可以看到Druid在内部pom文件中指定了SpringBoot版本
使用了spring-boot-dependencies 做为 Spring Boot的版本管理

在下方使用的依赖中,并无特别指定版本号则使用了默认的版本号
image.png

而我的项目所使用的Spring Boot版本号为 2.4.5

所以做的事情就很简单了

参考链接:
Druid Spring Boot Starter
Druid Spring Boot Starter 使用避坑 整合报错问题 Error creating bean with name ‘dataSource’
与spring-boot 2.2使用出错。

发表评论

您的电子邮箱地址不会被公开。