“SLF4J 日志绑定原理”的版本间的差异
跳到导航
跳到搜索
Jihongchang(讨论 | 贡献) (建立内容为“https://www.bilibili.com/video/BV1iJ411H74S?p=24”的新页面) |
Jihongchang(讨论 | 贡献) |
||
第1行: | 第1行: | ||
https://www.bilibili.com/video/BV1iJ411H74S?p=24 | https://www.bilibili.com/video/BV1iJ411H74S?p=24 | ||
+ | |||
+ | === 源码跟踪 === | ||
+ | |||
+ | ==== SLF4JTest.java ==== | ||
+ | <syntaxhighlight lang="java"> | ||
+ | …… | ||
+ | public class SLF4JTest { | ||
+ | |||
+ | public static final Logger LOGGER = LoggerFactory.getLogger(SLF4JTest.class); | ||
+ | …… | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ==== LoggerFactory.java ==== | ||
+ | <syntaxhighlight lang="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); | ||
+ | } | ||
+ | |||
+ | } | ||
+ | …… | ||
+ | } | ||
+ | </syntaxhighlight>调用顺序:LoggerFactory.getLogger(Class<?> clazz) | ||
+ | |||
+ | -> LoggerFactory.getLogger(String name) | ||
+ | |||
+ | -> LoggerFactory.getILoggerFactory() | ||
+ | |||
+ | -> LoggerFactory.performInitialization() | ||
+ | |||
+ | -> LoggerFactory.bind() |
2023年2月26日 (日) 13:41的版本
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()