阅读源码之前,首先提几个问题
这段文字摘录自官网:In your code, in addition to slf4j-api-1.8.0-beta2.jar, you simply drop one and only one binding of your choice onto the appropriate class path location. Do not place more than one binding on your class path.
带着上面的两个问题看下源码
// org/slf4j/slf4j-api/1.7.25/slf4j-api-1.7.25.jar!/org/slf4j/LoggerFactory.class private static final void bind() { // ... if (!isAndroid()) { // 查找日志框架的绑定 staticLoggerBinderPathSet = findPossibleStaticLoggerBinderPathSet(); reportMultipleBindingAmbiguity(staticLoggerBinderPathSet); } // ... } 复制代码
private static String STATIC_LOGGER_BINDER_PATH = "org/slf4j/impl/StaticLoggerBinder.class"; 复制代码
// org/slf4j/slf4j-api/1.7.25/slf4j-api-1.7.25.jar!/org/slf4j/LoggerFactory.class static Set<URL> findPossibleStaticLoggerBinderPathSet() { LinkedHashSet staticLoggerBinderPathSet = new LinkedHashSet(); try { ClassLoader loggerFactoryClassLoader = LoggerFactory.class.getClassLoader(); Enumeration paths; // 通过ClassLoader或者loggerFactoryClassLoader来获取Resources 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/apache/logging/log4j/log4j-slf4j-impl/2.11.1/log4j-slf4j-impl-2.11.1.jar!/org/slf4j/impl/StaticLoggerBinder.class // 这里的包名定义为org.slf4j.impl,使得上述第2步的Class Loader可以加载到这个类 package org.slf4j.impl; public final class StaticLoggerBinder implements LoggerFactoryBinder { // log4j init... } 复制代码
// ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3.jar!/org/slf4j/impl/StaticLoggerBinder.class // 这里的包名定义为org.slf4j.impl,使得上述第2步的Class Loader可以加载到这个类 package org.slf4j.impl; public class StaticLoggerBinder implements LoggerFactoryBinder { // logback init... } 复制代码
// org/slf4j/slf4j-jcl/1.7.25/slf4j-jcl-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class // 这里的包名定义为org.slf4j.impl,使得上述第2步的Class Loader可以加载到这个类 package org.slf4j.impl; public class StaticLoggerBinder implements LoggerFactoryBinder { // jcl init... } 复制代码
private static void reportMultipleBindingAmbiguity(Set<URL> binderPathSet) { if (isAmbiguousStaticLoggerBinderPathSet(binderPathSet)) { Util.report("Class path contains multiple SLF4J bindings."); Iterator i$ = binderPathSet.iterator(); while(i$.hasNext()) { URL path = (URL)i$.next(); Util.report("Found binding in [" + path + "]"); } Util.report("See http://www.slf4j.org/codes.html#multiple_bindings for an explanation."); } } 复制代码
代码中使用SLF4J来记录日志,可以任意切换底层日志框架而不需要修改代码,只需要更新依赖以及日志配置文件即可。