关于java:Slf4j-包老冲突-到底怎么解决

36次阅读

共计 2015 个字符,预计需要花费 6 分钟才能阅读完成。

作者: Jitwxs

链接: https://jitwxs.cn/e2390047.html

一、前言

在进行 Java 开发时,通常咱们会抉择 Slf4j 作为日志门面,但日志实现却不尽相同。如果零碎运行中同时存在多个日志实现,就会呈现相似下图的 Warning。

二、问题起因

咱们晓得 SpringBoot 默认应用的日志实现是 Logback,因而咱们尝试在我的项目中引入 Log4j 的依赖时,就复现了上图的报错。

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

上图报错告知咱们存在多个 SLF4J bingdings,别离位于 logback 和 log4j 包中,有两个 StaticLoggerBinder。

咱们晓得应用 Slf4j,须要 LoggerFactory.getLogger() 办法获取实例。

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

private final Logger logs = LoggerFactory.getLogger(xxx.class);
咱们就能够通过这个作为入口,去看看源码的实现。如下图所示,我标注了须要关注的外围代码。

(1)调用 getILoggerFactory() 办法失去 LoggerFactory。

(2)对于首次调用,INITIALIZATION_STATE 应该是 UNINITIALIZED,所以进入初始化的逻辑,调用办法 performInitialization()。

(3)调用 bind() 办法。

(4)如果不是 isAndroid(),调用

findPossibleStaticLoggerBinderPathSet() 办法,故名思意,查找可能的 staticLoggerBinder,留神这里返回的类型是 SET,即可能是多个。

(5)在 findPossibleStaticLoggerBinderPathSet() 这个办法内,首先通过 classLoader 加载了 org/slf4j/impl/StaticLoggerBinder.class 这个类的 path,它可能存在多个,因而应用了 while 获取了所有的 path,并最终返回。

(6)reportActualBinding() 办法会校验 SET 的 size,如果大于 1,就会打印出一开始咱们看见的 Warning 了。

三、问题解决

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

关上我的项目的 POM 文件,右键抉择 Diagrams -> Show Dependencies

假如咱们想要排除 logback 依赖,应用 log4j。Ctrl + F 搜寻 logback,能够找到援用该依赖的树形构造。

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

选中后成果如下:

如上图所示,logback 由 spring-boot-starter-logging 引入,最顶层是由 spring-boot-starter-web 和 spring-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>

近期热文举荐:

1.1,000+ 道 Java 面试题及答案整顿 (2021 最新版)

2. 别在再满屏的 if/ else 了,试试策略模式,真香!!

3. 卧槽!Java 中的 xx ≠ null 是什么新语法?

4.Spring Boot 2.5 重磅公布,光明模式太炸了!

5.《Java 开发手册(嵩山版)》最新公布,速速下载!

感觉不错,别忘了顺手点赞 + 转发哦!

正文完
 0