You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Spring Boot项目添加SLF4J时出现ClassPath多SLF4J绑定冲突问题求助

解决Spring Boot中SLF4J多绑定冲突问题

这个冲突是典型的日志依赖冲突场景:Spring Boot的所有spring-boot-starter-*组件默认引入了spring-boot-starter-logging模块,它集成了logback作为SLF4J的默认实现,同时已经包含了SLF4J API。而你手动添加了slf4j-log4j12(SLF4J到log4j 1.x的绑定),再加上依赖传递可能带来的其他绑定(比如错误里的slf4j-reload4j),就导致类路径中出现多个SLF4J的绑定实现,SLF4J无法确定使用哪一个,从而抛出警告。

下面给你两种可行的解决方案:

方案一:切换到Spring Boot官方支持的Log4j2(推荐)

Log4j 1.x已经停止维护,推荐使用更安全、功能更丰富的Log4j2。修改你的Gradle配置如下:

1. 调整依赖配置

移除手动添加的slf4j-apislf4j-log4j12,排除所有starter中的默认logback依赖,添加Spring Boot的Log4j2 starter:

dependencies {
    // 排除每个starter中的默认日志依赖
    implementation('org.springframework.boot:spring-boot-starter-data-jdbc') {
        exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
    }
    implementation('org.springframework.boot:spring-boot-starter-data-jpa') {
        exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
    }
    implementation('org.springframework.boot:spring-boot-starter-jdbc') {
        exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
    }
    implementation('org.springframework.boot:spring-boot-starter-web') {
        exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
    }
    // 其他原有依赖保留
    implementation 'org.springdoc:springdoc-openapi-ui:1.6.8'
    implementation 'org.hibernate.validator:hibernate-validator:7.0.4.Final'
    implementation 'org.mapstruct:mapstruct:1.4.2.Final'
    // 添加Log4j2 starter
    implementation 'org.springframework.boot:spring-boot-starter-log4j2'
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'
    annotationProcessor 'org.mapstruct:mapstruct-processor:1.4.2.Final'
    runtimeOnly 'com.h2database:h2'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.8.2'
}

2. 适配Log4j2配置

将原有的log4j.properties替换为Log4j2格式的配置文件(比如log4j2.properties),示例配置和你原有规则一致:

status = warn
name = PropertiesConfig

appenders = console

appender.console.type = Console
appender.console.name = STDOUT
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = %d{yyyy-MM-dd HH:mm} %t [%-5p]-%c:%m%n

rootLogger.level = all
rootLogger.appenderRefs = stdout
rootLogger.appenderRef.stdout.ref = STDOUT

方案二:继续使用Log4j 1.x(不推荐)

如果因特殊需求必须保留Log4j 1.x,按以下步骤修改:

1. 调整依赖配置

移除重复的slf4j-api(Spring Boot starter已包含),排除所有starter中的默认logback依赖,保留slf4j-log4j12绑定:

dependencies {
    // 排除每个starter中的默认日志依赖
    implementation('org.springframework.boot:spring-boot-starter-data-jdbc') {
        exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
    }
    implementation('org.springframework.boot:spring-boot-starter-data-jpa') {
        exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
    }
    implementation('org.springframework.boot:spring-boot-starter-jdbc') {
        exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
    }
    implementation('org.springframework.boot:spring-boot-starter-web') {
        exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
    }
    // 其他原有依赖保留
    implementation 'org.springdoc:springdoc-openapi-ui:1.6.8'
    implementation 'org.hibernate.validator:hibernate-validator:7.0.4.Final'
    implementation 'org.mapstruct:mapstruct:1.4.2.Final'
    // 保留Log4j 1.x绑定,移除重复的slf4j-api
    implementation 'org.slf4j:slf4j-log4j12:1.7.36'
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'
    annotationProcessor 'org.mapstruct:mapstruct-processor:1.4.2.Final'
    runtimeOnly 'com.h2database:h2'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testImplementation 'org.junit.jupiter:junit-jupiter-engine:5.8.2'
}

2. 保留原有配置

你的log4j.properties可以继续使用,无需修改。

验证依赖是否正确

修改完成后,执行以下Gradle命令查看运行时依赖树,确认没有多个SLF4J绑定:

./gradlew dependencies --configuration runtimeClasspath | grep slf4j

输出应该只包含你选择的绑定(方案一为log4j-slf4j-impl,方案二为slf4j-log4j12),不会同时出现logback-classicslf4j-reload4j

内容的提问来源于stack exchange,提问作者MohammadBaqer

火山引擎 最新活动