Java日志——日志框架与SLF4J的整合

三种日志框架与SLF4J的适配

之前已经介绍过了常用的JUL、Log4j、Logback等常用的日志框架,现将它们与SLF4J作一个整合。
先放一张SLF4J官网的图片,后面我们一点一点的来看。
在这里插入图片描述

Logback+SLF4J

对于Logback+SLF4J的使用,我们只需要引入logback-classic这个pom就行了,因为这个pom会自动帮我们引入logback-core、slf4j-api等pom。这种方式配置还是很简单的,Logback本身就支持SLF4J,所以新项目还是建议使用这个组合。

		<dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>

Log4j+SLF4J

使用这个组合时,slf4j-log4j12包已经有Log4j的依赖,因此不需要再单独引入log4j的api
在这里插入图片描述

		<dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.8.0-alpha2</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.25</version>
            <scope>compile</scope>
        </dependency>

在这里插入图片描述
从这个图我们能够看出,Log4j想要适配SLF4J还需要一个适配器,因为前者出现的更早,那时候没有SLF4J,所以自身也就没有兼容SLF4J,需要一个适配器来进行适配,这个适配器就是slf4j-log4j12。接下来我们通过源码来看一下究竟是slf4j-log4j12是怎样将Log4j与SLF4J适配到一起的:

// 应用层日志记录还是只用到了SLF4J包,并不能看出具体是哪一种日志实现。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Logger logger = LoggerFactory.getLogger(Test.class.getName());
// Logger只是一个顶层接口,我们知道现在用的是Log4j的日志实现,所以这个Logger应该是一个Log4j实现类的对象,那么我们点进LoggerFactory.getLogger这个方法
public static Logger getLogger(String name) {
      ILoggerFactory iLoggerFactory = getILoggerFactory();
      return iLoggerFactory.getLogger(name);
}
// Logger对象是根据ILoggerFactory得到的,ILoggerFactory又是一个接口,通过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这个类,发现点到了slf4j-log4j12这个包中。
// StaticLoggerBinder类的getLoggerFactory()方法返回了一个Log4jLoggerFactory对象,我们具体看一下Log4jLoggerFactory这个类
public Logger getLogger(String name) {
        Logger slf4jLogger = (Logger)this.loggerMap.get(name);
        if (slf4jLogger != null) {
            return slf4jLogger;
        } else {
            // 仍然是用Log4j那一套的Logger和LogManager生成一个Logger对象
            org.apache.log4j.Logger log4jLogger;
            if (name.equalsIgnoreCase("ROOT")) {
                log4jLogger = LogManager.getRootLogger();
            } else {
                log4jLogger = LogManager.getLogger(name);
            }
            // 这里将Log4j的Logger转为SLF4J的Logger,完成适配
            Logger newInstance = new Log4jLoggerAdapter(log4jLogger);
            Logger oldInstance = (Logger)this.loggerMap.putIfAbsent(name, newInstance);
            return (Logger)(oldInstance == null ? newInstance : oldInstance);
        }
    }

JUL+SLF4J

pom文件如下:

		<dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-jdk14</artifactId>
            <version>1.7.25</version>
        </dependency>


我们看到slf4j-jdk14有依赖slf4j-api,因此我们无需再单独引入slf4j-api。slf4j-jdk14适配JUL与SLF4J的原理和上面介绍slf4j-log4j12一样。同样是由slf4j-jdk14提供StaticLoggerBinder的实现,将JUL的Logger,封装成SLF4J的Logger类型,返回到应用层供程序调用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值