如果你看一下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还附带了它自己的伪org.slf4j.impl.StaticLoggerBinder
实现,可能是为了防止SLF4J开发期间的编译器错误(或者如果没有提供这样的StaticLoggerBinder
则作为无操作回退通过约束)。
因此,如果您的运行时类路径中有slf4j-api-1.7.5
和slf4j-simple-1.7.5
,那么您第一次使用时,例如Logger#info(String)
,就会定义StaticLoggerBinder
slf4j-simple
JAR将被选中 over StaticLoggerBinder
JAR中定义的slf4j-api
。
我试图了解这种“偏好”/优先级(绑定impl over api impl)是如何工作的。上述方法如何首先选择绑定的StaticLoggerBinder
而非假人StaticLoggerBinder
中提供了slf4j-api
?
提前致谢!
答案 0 :(得分:2)
虚拟StaticLoggerBinder根本不包含在slf4j-api jar文件中。
请参阅slf4j-api源代码here中的pom.xml。虚拟活页夹被删除。