如果您查看 slf4j-api 的源代码(任何现代版本,例如 1.7.5),则有一个LoggerFactory
具有以下方法的类:
private static Set findPossibleStaticLoggerBinderPathSet() {
// use Set instead of list in order to deal with bug #138
// LinkedHashSet appropriate here because it preserves insertion order during iteration
Set 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 ioe) {
Util.report("Error getting resources from path", ioe);
}
return staticLoggerBinderPathSet;
}
当您调用任何Logger
方法(调试、信息、警告、错误等)并且 SLF4J 绑定尚未初始化时,将调用此方法。这就是 SLF4J 如何确定在运行时使用哪个绑定。
基本上,为 SLF4J 编写正确绑定的一种方法是实现您自己的org.slf4j.impl.StaticLoggerBinder
类。但是,slf4j-api
JAR 也带有它自己的虚拟实现,可能是为了防止 SLF4J 开发期间的编译器错误(或者如果绑定org.slf4j.impl.StaticLoggerBinder
没有提供这样的功能,则作为无操作后备)。StaticLoggerBinder
因此,如果您有slf4j-api-1.7.5
并且slf4j-simple-1.7.5
在您的运行时类路径上,那么当您第一次使用时,例如, JARLogger#info(String)
中StaticLoggerBinder
定义的slf4j-simple
将被选择而不是JAR中StaticLoggerBinder
定义的slf4j-api
。
我试图了解这种“偏好”/优先级(绑定 impl over api impl)是如何工作的。上述方法如何首先选择绑定而不是提供StaticLoggerBinder
的虚拟对象?StaticLoggerBinder
slf4j-api
提前致谢!