开发技巧青春校园java高级开发群

Slf4j 包老冲突,每次排查半天,是什么原因?怎么解决?

2021-01-13  本文已影响0人  程序员知识圈

一、前言

在进行 Java 开发时,通常我们会选择 Slf4j 作为日志门面,但日志实现却不尽相同。如果系统运行中同时存在多个日志实现,就会出现类似下图的 Warning

图片

二、问题原因

我们知道SpringBoot默认使用的日志实现是 Logback,因此我们尝试在项目中引入 Log4j的依赖时,就复现了上图的报错。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>

上图报错告知我们存在多个 SLF4J bingdings,分别位于 logbacklog4j包中,有两个 StaticLoggerBinder
我们知道使用Slf4j,需要 LoggerFactory.getLogger() 方法获取实例。

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

private final Logger logs = LoggerFactory.getLogger(xxx.class);

我们就可以通过这个作为入口,去看看源码的实现。如下图所示,我标注了需要关注的核心代码。

图片 图片

三、问题解决

解决思路就是将你不想要的日志实现从依赖包中排除掉即可,通过 IDEA提供的 Diagrams能够非常方便的查看项目中的依赖关系。

打开项目的POM文件,右键选择Diagrams -> Show Dependencies

图片

假设我们想要排除logback 依赖,使用 log4j。Ctrl + F 搜索logback,可以找到引用该依赖的树形结构。

图片

点击窗口左上角的下图中的这个图标,可以只看当前选中的这个依赖的关系。

图片

选中后效果如下:

图片

如上图所示,logbackspring-boot-starter-logging 引入,最顶层是由spring-boot-starter-webspring-boot-starter-test引入。

我们尝试在 spring-boot-starter-web 中排除该依赖,应该就可以了。如果排出后重新搜索仍然存在 logback 依赖,则重复执行排除的操作。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </exclusion>
    </exclusions>
</dependency>

四、总结

日志框架冲突特别对于新手来说处理起来比较头疼,因为涉及到了日志接口和日志实现.
我们推崇的应该是面向接口编程,因此我们大到开源项目,小到公司的公共jar包,应当合理利用 Maven 的传递机制。具体的日志实现不应该传递出去,避免影响到调用的下游方。

<optional>true</optional>
上一篇 下一篇

猜你喜欢

热点阅读