- 源码前篇
- 源码后篇
- 但是。。。
上一篇文章还在用log.isDebugEnabled()判断debug日志?你out了中写了使用日志框架的一些架构设计,其核心就是外观(门面)模式,这篇接着上文,通过分析slf4j源码来进一步理解这个设计模式。
源码前篇请查看悟空没有尾大神写的slf4j源码解析-门面模式
我就狗尾续貂,接着大神的文章接着详细的往下写
static SetfindPossibleStaticLoggerBinderPathSet() { // 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 = paths.nextElement(); staticLoggerBinderPathSet.add(path); } } catch (IOException ioe) { Util.report("Error getting resources from path", ioe); } return staticLoggerBinderPathSet; }
这里就是精髓了, 通过ClassLoader.getResources 去项目的资源目录下寻找org/slf4j/impl/StaticLoggerBinder.class 文件,如果找到多个的StaticLoggerBinderclass文件,就会在reportMultipleBindingAmbiguity中判断,并将每个StaticLoggerBinder文件路径打印出来。这里就解释了为什么slf4j 不能同时整合多个日志框架。
SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar:file:/Document/Service/Maven/apache-maven-3.6.3/repository/ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: Found binding in [jar:file:/Document/Service/Maven/apache-maven-3.6.3/repository/org/slf4j/slf4j-log4j12/1.7.21/slf4j-log4j12-1.7.21.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation. SLF4J: Actual binding is of type [ch.qos.logback.classic.util.ContextSelectorStaticBinder]
查看STATIC_LOGGER_BINDER_PATH 的源码可知
// 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";
它要寻找的类为org/slf4j/impl/StaticLoggerBinder.class,然后去找这个文件的位置发现在slf4j的源码下并没有找个这个文件,甚至连这个路径都是不存在的。
注释的翻译
还记得门面模式是如何设计的吗?如果记得,就应该明白这个是咋回事了,slf4j作为门面,只会提供高级的接口,具体的实现是其他日志框架需要做的,所以这个类,你需要到其他日志框架里找,这里通过logback来找找看,因为springboot默认就是使用的slf4j+logback
这是logback的目录结构,可以看到里面确实有。
开发环境,我们能看到全部的引用jar包,可是到我们开发完成,打成可运行的jar包的时候呢?
这是我从我的可运行的springboot jar包中的lib目录下找到的logback的jar包,和它的解压文件夹。
想想,jar包是如何启动运行找到这个jar包中,它所需要的文件的呢?我们下篇文章见,
java的类加载机制



