在slf4j的文档中,它说绑定发生在complie时间:
"SLF4J不依赖于任何特殊的类加载器机器.实际上,每个SLF4J绑定在编译时都是硬连线使用一个且只有一个特定的日志框架.例如,slf4j-log4j12-1.7.5.jar绑定绑定在编译时使用log4j.在您的代码中,除了slf4j-api-1.7.5.jar之外,您只需将您选择的一个且只有一个绑定放到相应的类路径位置.不要在您的代码上放置多个绑定类路径.这是一般概念的图解说明." http://www.slf4j.org/manual.html
这是如何运作的?
这也是我的问题,我想添加我的答案,因为发现其他两个答案不够清楚(尽管完全正确)。
LoggerFactory.bind()首先,检查in的实现中的这一行slf4j-api(链接)
// the next line does the binding
StaticLoggerBinder.getSingleton();
Run Code Online (Sandbox Code Playgroud)
有一个类叫做org.slf4j.impl.StaticLoggerBinder. 在github上检查其实现。
现在继续从中央 Maven 存储库下载slf4j-api.jar,解压并查找StaticLoggerBinder.class文件。
不要尝试!你不能。事实上,整个产品org.slf4j.impl已从包装中取出。检查pom.xml项目的情况:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<phase>process-classes</phase>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
<configuration>
<tasks>
<echo>Removing slf4j-api's dummy StaticLoggerBinder and StaticMarkerBinder</echo>
<delete dir="target/classes/org/slf4j/impl"/>
</tasks>
</configuration>
</plugin>
Run Code Online (Sandbox Code Playgroud)
最后,检查 SLF4j 的绑定包之一,例如slf4j-simple。能找到org.slf4j.impl.StaticLoggerBinder课吗?
总之,当slf4j-api.jar您的运行时环境中只有一个(且只有一个)绑定包时,您就只有一个org.slf4j.impl.StaticLoggerBinder执行绑定的类。
这是slf4j的源代码.Slf4j将在类路径中找到路径为" org/slf4j/impl/StaticLoggerBinder.class "的所有类.如果有多个,jvm将只随机选取一个.有关详细信息,请参阅此处:http://www.slf4j.org/codes.html#multiple_bindings
// We need to use the name of the StaticLoggerBinder class, but we can't
// reference
// the class itself.
private static String STATIC_LOGGER_BINDER_PATH = "org/slf4j/impl/StaticLoggerBinder.class";
static Set<URL> findPossibleStaticLoggerBinderPathSet() {
// use Set instead of list in order to deal with bug #138
// LinkedHashSet appropriate here because it preserves insertion order
// during iteration
Set<URL> staticLoggerBinderPathSet = new LinkedHashSet<URL>();
try {
ClassLoader loggerFactoryClassLoader = LoggerFactory.class.getClassLoader();
Enumeration<URL> paths;
if (loggerFactoryClassLoader == null) {
paths = ClassLoader.getSystemResources(STATIC_LOGGER_BINDER_PATH);
} else {
paths = loggerFactoryClassLoader.getResources(STATIC_LOGGER_BINDER_PATH);
}
while (paths.hasMoreElements()) {
URL path = paths.nextElement();
staticLoggerBinderPathSet.add(path);
}
} catch (IOException ioe) {
Util.report("Error getting resources from path", ioe);
}
return staticLoggerBinderPathSet;
}
Run Code Online (Sandbox Code Playgroud)
据我所知,它通过期望类 StaticLoggingBinder 位于同一个包(org.slf4j.impl)中来实现这一点,而不管实现如何 - 所以它总是在同一个地方找到它。
| 归档时间: |
|
| 查看次数: |
2142 次 |
| 最近记录: |