“SLF4J 日志绑定原理”的版本间的差异
跳到导航
跳到搜索
Jihongchang(讨论 | 贡献) |
Jihongchang(讨论 | 贡献) |
||
第123行: | 第123行: | ||
-> LoggerFactory.bind() | -> LoggerFactory.bind() | ||
− | -> LoggerFactory.findPossibleStaticLoggerBinderPathSet() | + | -> LoggerFactory.findPossibleStaticLoggerBinderPathSet()<syntaxhighlight lang="java"> |
+ | private static String STATIC_LOGGER_BINDER_PATH = "org/slf4j/impl/StaticLoggerBinder.class"; | ||
+ | |||
+ | static Set<URL> findPossibleStaticLoggerBinderPathSet() { | ||
+ | Set<URL> staticLoggerBinderPathSet = new LinkedHashSet(); | ||
+ | |||
+ | try { | ||
+ | ClassLoader loggerFactoryClassLoader = LoggerFactory.class.getClassLoader(); | ||
+ | Enumeration paths; | ||
+ | if (loggerFactoryClassLoader == null) { | ||
+ | paths = ClassLoader.getSystemResources(STATIC_LOGGER_BINDER_PATH); | ||
+ | } else { | ||
+ | paths = loggerFactoryClassLoader.getResources(STATIC_LOGGER_BINDER_PATH); | ||
+ | } | ||
+ | |||
+ | while(paths.hasMoreElements()) { | ||
+ | URL path = (URL)paths.nextElement(); | ||
+ | staticLoggerBinderPathSet.add(path); | ||
+ | } | ||
+ | } catch (IOException var4) { | ||
+ | Util.report("Error getting resources from path", var4); | ||
+ | } | ||
+ | |||
+ | return staticLoggerBinderPathSet; | ||
+ | } | ||
+ | </syntaxhighlight>org.slf4j.impl.StaticLoggerBinder.java<syntaxhighlight lang="java"> | ||
+ | package org.slf4j.impl; | ||
+ | …… | ||
+ | public class StaticLoggerBinder implements LoggerFactoryBinder { | ||
+ | …… | ||
+ | private final ILoggerFactory loggerFactory = new JDK14LoggerFactory(); | ||
+ | …… | ||
+ | } | ||
+ | </syntaxhighlight>JDK14LoggerFactory.java<syntaxhighlight lang="java"> | ||
+ | package org.slf4j.impl; | ||
+ | …… | ||
+ | public class JDK14LoggerFactory implements ILoggerFactory { | ||
+ | …… | ||
+ | public JDK14LoggerFactory() { | ||
+ | java.util.logging.Logger.getLogger(""); | ||
+ | } | ||
+ | …… | ||
+ | } | ||
+ | </syntaxhighlight> |
2023年2月26日 (日) 13:50的版本
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()
private static String STATIC_LOGGER_BINDER_PATH = "org/slf4j/impl/StaticLoggerBinder.class";
static Set<URL> findPossibleStaticLoggerBinderPathSet() {
Set<URL> staticLoggerBinderPathSet = new LinkedHashSet();
try {
ClassLoader loggerFactoryClassLoader = LoggerFactory.class.getClassLoader();
Enumeration paths;
if (loggerFactoryClassLoader == null) {
paths = ClassLoader.getSystemResources(STATIC_LOGGER_BINDER_PATH);
} else {
paths = loggerFactoryClassLoader.getResources(STATIC_LOGGER_BINDER_PATH);
}
while(paths.hasMoreElements()) {
URL path = (URL)paths.nextElement();
staticLoggerBinderPathSet.add(path);
}
} catch (IOException var4) {
Util.report("Error getting resources from path", var4);
}
return staticLoggerBinderPathSet;
}
org.slf4j.impl.StaticLoggerBinder.java
package org.slf4j.impl;
……
public class StaticLoggerBinder implements LoggerFactoryBinder {
……
private final ILoggerFactory loggerFactory = new JDK14LoggerFactory();
……
}
JDK14LoggerFactory.java
package org.slf4j.impl;
……
public class JDK14LoggerFactory implements ILoggerFactory {
……
public JDK14LoggerFactory() {
java.util.logging.Logger.getLogger("");
}
……
}