在slf4j api中存在类org.slf4j.impl.StaticLoggerBinder,org.slf4j.impl.StaticMarkerBinder,org.slf4j.impl.StaticMDCBinder。但是每个绑定到具体记录器的应该包含相同的类。
例如:
java类加载器如何替代它?这不应该是一个例外吗?
答案 0 :(得分:3)
如果您提取实际的slf4j-api jar,您会注意到org.slf4j.impl.StaticLoggerBinder
实际上并未包含在jar中。 SFL4J api是在构建时针对类编译的,但它实际上并未包含在工件中。如果你在api模块中查看org.slf4j.impl.StaticLoggerBinder
的源代码,它没有实现,所有公共实例方法抛出UnsupportedOperationException
。这没关系,因为该类被排除在slf4j-api jar之外。
类加载器行为正常,并选择在需要加载类时找到的org.slf4j.impl.StaticLoggerBinder
的第一个版本。这通常来自它在类路径中列出的第一个slf4j实现jar。
注意:
findPossibleStaticLoggerBinderPathSet()
仅用于警告类路径上存在多个绑定。它实际上并没有加载任何绑定。
答案 1 :(得分:1)
嗯,好的问题是slf4j
假设不使用运行时加载类。它看起来在启动时使用类加载器检查以下方法:
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;
}
@Dev是对的 - org.slf4j.impl.StaticLoggerBinder
仅包含在slf4j-api源中而不包含在二进制文件中 - 由于编译原因,仅包含在源代码中是一个简单的技巧。可以理解,findPossibleStaticLoggerBinderPathSet
仅用于记录目的。