场景
一个简单的spring-boot程序,需要用kafka做消息队列,于是在maven中引入kafka依赖,一切看似没问题,在启动时,打印出Warning信息:
SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar:file:/xxx/learning-slf4j-multiple-bindings/WEB-INF/lib/logback-classic-1.2.3.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: Found binding in [jar:file:/xxx/learning-slf4j-multiple-bindings/WEB-INF/lib/slf4j-log4j12-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.原因分析
通过警告消息,可以简单的看出是slf4j绑定发生问题,有多个StaticLoggerBinder.class存在,即slf4j-log4j12和logback-classic冲突。
- 疑惑点1是我并没有手动引入
slf4j-log4j12依赖,依赖jar包是被自动引入的,通过maven自带工具分析依赖路径,可以看出是kafka依赖于slf4j-log4j12,自动导入的依赖包。


- 日志绑定的机制分析
从日志对象开始探究slf4j的绑定方式。
import org.slf4j.Logger; import org.slf4j.LoggerFactory; ··· private final Logger logs = LoggerFactory.getLogger(***.class);LoggerFactory.getLogger()方法:(下述均只保留关键逻辑代码 )
public static Logger getLogger(Class<?> clazz) { Logger logger = getLogger(clazz.getName()); ··· return logger; } public static Logger getLogger(String name) { ILoggerFactory iLoggerFactory = getILoggerFactory();//看这里 return iLoggerFactory.getLogger(name);//根据名字返回一个Logger实例对象 }ILoggerFactory是一个接口,归属package org.slf4j;仅存在一个方法为:public Logger getLogger(String name);
接下来就是看看getILoggerFactory()的真面目:
public static ILoggerFactory getILoggerFactory() { if (INITIALIZATION_STATE == UNINITIALIZED) { synchronized (LoggerFactory.class) { if (INITIALIZATION_STATE == UNINITIALIZED) { INITIALIZATION_STATE = ONGOING_INITIALIZATION; performInitialization();//看这里 } } } switch (INITIALIZATION_STATE) { case SUCCESSFUL_INITIALIZATION: return StaticLoggerBinder.getSingleton().getLoggerFactory(); case NOP_FALLBACK_INITIALIZATION:
