SLF4J 日志绑定原理
https://www.bilibili.com/video/BV1iJ411H74S?p=24
源码跟踪
SLF4JTest.java
……
public class SLF4JTest {
public static final Logger LOGGER = LoggerFactory.getLogger(SLF4JTest.class);
……
}
LoggerFactory.java
……
public final class LoggerFactory {
……
public static Logger getLogger(String name) {
ILoggerFactory iLoggerFactory = getILoggerFactory();
return iLoggerFactory.getLogger(name);
}
public static Logger getLogger(Class<?> clazz) {
Logger logger = getLogger(clazz.getName());
if (DETECT_LOGGER_NAME_MISMATCH) {
Class<?> autoComputedCallingClass = Util.getCallingClass();
if (autoComputedCallingClass != null && nonMatchingClasses(clazz, autoComputedCallingClass)) {
Util.report(String.format("Detected logger name mismatch. Given name: \"%s\"; computed name: \"%s\".", logger.getName(), autoComputedCallingClass.getName()));
Util.report("See http://www.slf4j.org/codes.html#loggerNameMismatch for an explanation");
}
}
return logger;
}
……
public static ILoggerFactory getILoggerFactory() {
if (INITIALIZATION_STATE == 0) {
Class var0 = LoggerFactory.class;
synchronized(LoggerFactory.class) {
if (INITIALIZATION_STATE == 0) {
INITIALIZATION_STATE = 1;
performInitialization();
}
}
}
switch (INITIALIZATION_STATE) {
case 1:
return SUBST_FACTORY;
case 2:
throw new IllegalStateException("org.slf4j.LoggerFactory in failed state. Original exception was thrown EARLIER. See also http://www.slf4j.org/codes.html#unsuccessfulInit");
case 3:
return StaticLoggerBinder.getSingleton().getLoggerFactory();
case 4:
return NOP_FALLBACK_FACTORY;
default:
throw new IllegalStateException("Unreachable code");
}
}
……
private static final void performInitialization() {
bind();
if (INITIALIZATION_STATE == 3) {
versionSanityCheck();
}
}
……
private static final void bind() {
String msg;
try {
Set<URL> staticLoggerBinderPathSet = null;
if (!isAndroid()) {
staticLoggerBinderPathSet = findPossibleStaticLoggerBinderPathSet();
reportMultipleBindingAmbiguity(staticLoggerBinderPathSet);
}
StaticLoggerBinder.getSingleton();
INITIALIZATION_STATE = 3;
reportActualBinding(staticLoggerBinderPathSet);
fixSubstituteLoggers();
replayEvents();
SUBST_FACTORY.clear();
} catch (NoClassDefFoundError var2) {
msg = var2.getMessage();
if (!messageContainsOrgSlf4jImplStaticLoggerBinder(msg)) {
failedBinding(var2);
throw var2;
}
INITIALIZATION_STATE = 4;
Util.report("Failed to load class \"org.slf4j.impl.StaticLoggerBinder\".");
Util.report("Defaulting to no-operation (NOP) logger implementation");
Util.report("See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.");
} catch (NoSuchMethodError var3) {
msg = var3.getMessage();
if (msg != null && msg.contains("org.slf4j.impl.StaticLoggerBinder.getSingleton()")) {
INITIALIZATION_STATE = 2;
Util.report("slf4j-api 1.6.x (or later) is incompatible with this binding.");
Util.report("Your binding is version 1.5.5 or earlier.");
Util.report("Upgrade your binding to version 1.6.x.");
}
throw var3;
} catch (Exception var4) {
failedBinding(var4);
throw new IllegalStateException("Unexpected initialization failure", var4);
}
}
……
}
调用顺序:LoggerFactory.getLogger(Class<?> clazz)
-> LoggerFactory.getLogger(String name)
-> LoggerFactory.getILoggerFactory()
-> LoggerFactory.performInitialization()
-> LoggerFactory.bind()
-> LoggerFactory.findPossibleStaticLoggerBinderPathSet()