码迷,mamicode.com
首页 > 其他好文 > 详细

slf4j作用及其实现原理

时间:2018-04-08 14:33:14      阅读:165      评论:0      收藏:0      [点我收藏+]

标签:系统   back   原理   不同的   uri   一个   nts   return   resources   

为什么要使用slf4j

现实场景:

我们自己的系统中使用了logback这个日志系统

我们的系统使用了A.jar,A.jar中使用的日志系统为log4j

我们的系统又使用了B.jar,B.jar中使用的日志系统为slf4j-simple

这样,我们的系统就不得不同时支持并维护logback、log4j、slf4j-simple三种日志框架,非常不便。

解决这个问题的方式就是引入一个适配层,由适配层决定使用哪一种日志系统,而调用端只需要做的事情就是打印日志而不需要关心如何打印日志,slf4j或者commons-logging就是这种适配层。

从上面的描述,我们清楚地知道一点:slf4j只是一个日志标准,并不是日志系统的具体实现

理解这句话非常重要,slf4j只做两件事情

  • 提供日志接口
  • 提供获取具体日志对象的方法

slf4j-simple、logback-classic都是slf4j的具体实现,log4j并不直接实现slf4j,但是有专门的一层桥接slf4j-log4j12来实现slf4j。

slf4j实现原理

slf4j的用法就是一句"Logger logger = LoggerFactory.getLogger(Object.class);"

可见这里就是通过LoggerFactory去拿slf4j提供的一个Logger接口的具体实现而已。getLogger的时候会去classpath下找STATIC_LOGGER_BINDER_PATH,即所有slf4j的实现,在提供的jar包路径下,一定是有"org/slf4j/impl/StaticLoggerBinder.class"存在的。

    private static String STATIC_LOGGER_BINDER_PATH = "org/slf4j/impl/StaticLoggerBinder.class";

    private 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;
    }

我们不能避免在系统中同时引入多个slf4j的实现,所以接收的地方是一个Set。

同时存在多个"org/slf4j/impl/StaticLoggerBinder.class"怎么办?

首先确定的是这不会导致启动报错只会打印warnning,其次在这种情况下编译期间,编译器会选择其中一个StaticLoggerBinder.class进行绑定,sfl4j也在reportActualBinding方法中报告了绑定的是哪个日志框架。

StaticLoggerBinder就比较简单了,不同的StaticLoggerBinder其getLoggerFactory实现不同,拿到ILoggerFactory之后调用一下getLogger即拿到了具体的Logger,可以使用Logger进行日志输出。

 

slf4j作用及其实现原理

标签:系统   back   原理   不同的   uri   一个   nts   return   resources   

原文地址:https://www.cnblogs.com/wade-luffy/p/8744401.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!