zoukankan      html  css  js  c++  java
  • slf4j介绍以及与Log4j、Log4j2、LogBack整合方法

    翻了一下百度和官网。这么介绍slf4j。

      slf4j 全称 Simple Logging Facade for Java,是日志框架的一种抽象,那么也就是说 slf4j 是不能单独使用的必须要有其他实现日志框架来配合使用,并且如果要启用slf4j框架要导入slf4j-api-xxx.jar 这个包, 这个包是slf4j 实现各种支持的日志框架的包比如log4j、log4j2、logback等。  slf4j也已经支持这几种日志组件。

      这里拿slf4j 和logback的整合使用为例,先来看依赖关系

      简单的从浅层源码来查找依赖关系

      通常我们在java类中使用日志要先拿到Logger,如:

      private static final Logger          LOGGER        = LoggerFactory.getLogger(Test.class);

      我们来看getLogger方法的代码,注意 getLogger 这个静态方法是属于 slf4j-api-xxx.jar的org.slf4j包下的。

    public static Logger getLogger(Class<?> clazz) {
            Logger logger = getLogger(clazz.getName());
            if (DETECT_LOGGER_NAME_MISMATCH) {
                Class<?> autoComputedCallingClass = Util.getCallingClass();
                if (autoComputedCallingClass != null && nonMatchingClasses(clazz, autoComputedCallingClass)) {
                    Util.report(String.format("Detected logger name mismatch. Given name: "%s"; computed name: "%s".", logger.getName(),
                                    autoComputedCallingClass.getName()));
                    Util.report("See " + LOGGER_NAME_MISMATCH_URL + " for an explanation");
                }
            }
            return logger;
        }

     继续看方法第一行 getLogger的代码

     public static Logger getLogger(String name) { ILoggerFactory iLoggerFactory = getILoggerFactory(); return iLoggerFactory.getLogger(name); } 

    继续看getILoggerFactory方法

    public static ILoggerFactory getILoggerFactory() {
            if (INITIALIZATION_STATE == UNINITIALIZED) {
                synchronized (LoggerFactory.class) {
                    if (INITIALIZATION_STATE == UNINITIALIZED) {
                        INITIALIZATION_STATE = ONGOING_INITIALIZATION;
                        performInitialization();
                    }
                }
            }
            switch (INITIALIZATION_STATE) {
            case SUCCESSFUL_INITIALIZATION:
                return StaticLoggerBinder.getSingleton().getLoggerFactory();
            case NOP_FALLBACK_INITIALIZATION:
                return NOP_FALLBACK_FACTORY;
            case FAILED_INITIALIZATION:
                throw new IllegalStateException(UNSUCCESSFUL_INIT_MSG);
            case ONGOING_INITIALIZATION:
                // support re-entrant behavior.
                // See also http://jira.qos.ch/browse/SLF4J-97
                return SUBST_FACTORY;
            }
            throw new IllegalStateException("Unreachable code");
        }

    注意看:StaticLoggerBinder.getSingleton().getLoggerFactory();    其中StaticLoggerBinder 类是 logback-classic-xxx.jar 包下的 并且实现了 slfj-api-xxx.jar包的 LoggerFactoryBinder接口。 也就是说在 slf4j-api-xxx.jar包下的 getILoggerFactory 方法中调用了logback-classic-xxx.jar 包的StaticLoggerBinder类中的方法并且 该类实现了slf4j-api-xxx.jar 中的 LoggerFactoryBinder接口。 

    public ILoggerFactory getLoggerFactory() {
            if (!initialized) {
                return defaultLoggerContext;
            }
    
            if (contextSelectorBinder.getContextSelector() == null) {
                throw new IllegalStateException("contextSelector cannot be null. See also " + NULL_CS_URL);
            }
            return contextSelectorBinder.getContextSelector().getLoggerContext();
        }

    而在getLoggerContext()方法中  StatusPrinter.printInCaseOfErrorsOrWarnings(loggerContext)  这段代码传入的参数是LoggerContext 是logback-class-xxx.jar 包中的。 并且StatusPrinter类是 logback-core-xxx.jar包中的。

    这样就形成了继承关系为:  logback-core-xxx.jar  -->  logback-classic-xxx.jar --> slf4j-api-xxx.jar --> 自己的代码。

    可能有疑问是slf4j怎样知道与谁整合拿谁的LoggerFactory , 其实是通过不同的jar包来实现的。

      slf4j与log4j整合导入的jar包为

      1. slf4j-api.jar
      2. slf4j-log4j12.jar
      3. log4j.jar

      slf4j与log4j2整合导入的jar包为:

      1. slf4j-api.jar
      2. log4j-slf4j-impl.jar
      3. log4j-api.jar
      4. log4j-core.jar

      slf4j与logback整合导入的jar包为:

      1. slf4j-api.jar
      2. logback-core.jar
      3. logback-classic.jar

      所以这样当更换日志框架的时候 slf4j接口是不用动的,只需要换下对应的实现框架的包就可以了。并且代码不用更改。

     

    本文纯属原创, 转载请注明出处!

  • 相关阅读:
    提纲挈领webrtc之vad检测
    提纲挈领webrtc音频处理算法之写在前面的话
    搭建git远程服务器三步骤
    详解m4文件
    chrome浏览器被reimage pair 劫持怎么处理
    linux查看系统32位还是64位
    git gc和fsck的用法
    ubuntu 16.04 的64位 安装arm-none-linux-gnueabi-gcc的步骤和问题解决
    利用终端命令实现进入ntfs分区有两种方法。
    ubuntu-14.10下,安装gcc交叉编译器遇到问题及解决方法
  • 原文地址:https://www.cnblogs.com/qiaoyutao/p/11052953.html
Copyright © 2011-2022 走看看