SLF4J的全称是 Simple Logging Facade for Java(简单java日志门面)

SLF4J自己不提供具体的日志功能实现,只是提供了一个统一的日志门面,在这个统一的门面之下,用户可以选择他们喜欢的日志的具体实现。

考虑下面一个场景:我们对外提供的工具包使用了log4j来管理日志,另外一个团队如果使用logback来管理他们的日志,在引入我们提供的工具包之后他们的项目中就会有两个不同的日志管理API,使用SLF4J可以解决这个问题。我们可以使用SLF4J + log4j来开发我们的工具包,客户端在使用我们的API的时候可以不用引入log4j的包

我们在使用SLF4J的时候通常使用下面的方式来得到Logger

Logger logger = LoggerFactory.getLogger(ClassName); //Logger 和LoggerFactory都是 slf4j-api.jar中 org.slf4j包下边的类

下边是getLogger的定义:

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

getILoggerFactory()方法最终调用的是 LoggerFactory的bind()方法来确定具体是加载哪个日志的实现

private final static void bind() {
try {
Set<URL> staticLoggerBinderPathSet = null;
// skip check under android, see also http://jira.qos.ch/browse/SLF4J-328
if (!isAndroid()) {
staticLoggerBinderPathSet = findPossibleStaticLoggerBinderPathSet();
reportMultipleBindingAmbiguity(staticLoggerBinderPathSet);
}
// the next line does the binding
StaticLoggerBinder.getSingleton();
INITIALIZATION_STATE = SUCCESSFUL_INITIALIZATION;
reportActualBinding(staticLoggerBinderPathSet);
replayEvents();
} catch (NoClassDefFoundError ncde) {
String msg = ncde.getMessage();
if (messageContainsOrgSlf4jImplStaticLoggerBinder(msg)) {
INITIALIZATION_STATE = NOP_FALLBACK_INITIALIZATION;
Util.report("Failed to load class \"org.slf4j.impl.StaticLoggerBinder\".");
Util.report("Defaulting to no-operation (NOP) logger implementation");
Util.report("See " + NO_STATICLOGGERBINDER_URL + " for further details.");
} else {
failedBinding(ncde);
throw ncde;
}
} catch (java.lang.NoSuchMethodError nsme) {
String msg = nsme.getMessage();
if (msg != null && msg.contains("org.slf4j.impl.StaticLoggerBinder.getSingleton()")) {
INITIALIZATION_STATE = FAILED_INITIALIZATION;
Util.report("slf4j-api 1.6.x (or later) is incompatible with this binding.");
Util.report("Your binding is version 1.5.5 or earlier.");
Util.report("Upgrade your binding to version 1.6.x.");
}
throw nsme;
} catch (Exception e) {
failedBinding(e);
throw new IllegalStateException("Unexpected initialization failure", e);
}
}

findPossibleStaticLoggerBinderPathSet()方法会在calsspath中寻找名为org.slf4j.impl.StaticLoggerBinder的类来确定项目中有哪些具体的日志实现

针对log4j来说,我们如果要使用SLF4J + log4j 来管理我们的日志,则需要三个相关的jar包(slf4j-api.jar、slf4j-log4j12.jar、log4j.jar)。slf4j-api.jar中有Logger、LoggerFactory等相应的类,slf4j-log4j12.jar中有org.slf4j.impl.StaticLoggerBinder 以及相应的 Log4jLoggerFactory 和能将log4j的Logger转换为slf4j的Logger的Log4jLoggerAdapter(下图是slf4j-log4j.jar中包含的类,一共6个:)

org.slf4j.impl.StaticLoggerBinder 类中绑定了Log4jLoggerFactory,在Log4jLoggerFactory的getLogger(String name)方法中使用 Log4jLoggerAdapter来实现了对log4j的注入:

    public Logger getLogger(String name) {
Logger slf4jLogger = loggerMap.get(name);
if (slf4jLogger != null) {
return slf4jLogger;
} else {
org.apache.log4j.Logger log4jLogger;
if (name.equalsIgnoreCase(Logger.ROOT_LOGGER_NAME))
log4jLogger = LogManager.getRootLogger();
else
log4jLogger = LogManager.getLogger(name); Logger newInstance = new Log4jLoggerAdapter(log4jLogger);
Logger oldInstance = loggerMap.putIfAbsent(name, newInstance);
return oldInstance == null ? newInstance : oldInstance;
}
}

slf4j + log4j 是如何初始化的的更多相关文章

  1. slf4j log4j logback关系详解和相关用法

    slf4j log4j logback关系详解和相关用法 写java也有一段时间了,一直都有用slf4j log4j输出日志的习惯.但是始终都是抱着"拿来主义"的态度,复制粘贴下配 ...

  2. slf4j,log4j,logback 初步使用

    log4j,slf4j,logback简单介绍见 LogBack简易教程 Logback浅析 简单的将,slf4j是一个日志的框架,有各种日志的接口,但是并不包含实际的写日志的方法. log4j,lo ...

  3. slf4j+log4j在Java中实现日志记录

    小Alan今天来跟大家聊聊开发中既简单又常用但必不可少的一样东西,那是什么呢?那就是日志记录,日志输出,日志保存. 后面就统一用日志记录四个字来形容啦. 日志记录是项目的开发中必不可少的一个环节,特别 ...

  4. Spring中配置使用slf4j + log4j

    本人也是查看别人博客获得的方法,详细讲解请参照 https://www.cnblogs.com/yuxiaole/p/9297266.html 下面进入正题: 1.在pom.xml中注入相关的依赖 & ...

  5. 常见java日志系统的搭配详解:关于slf4j log4j log4j2 logback jul jcl commons-logging jdk-logging

    先看一张图: 是不是有点晕, 晕就对了.这个仅仅是 slf4j 的情况,实际上, 我们不仅要接触到 slf4j ,有时候还会接触其他的日志系统.且看下文分解. 1 直接使用各个日志系统 1.1 直接使 ...

  6. 在android中配置 slf4j + log4j 日志记录框架

    需求: 在项目开发中,需要记录 操作日志 .起初自己写了个简单的日志记录文本写入到文本的方法,后来随着项目的膨胀,需要考虑更多的操作,开始考虑性能问题. 实现: 考虑使用 slf4j + log4j ...

  7. slf4j log4j logback相关用法

    Java的简单日志门面( Simple Logging Facade for Java SLF4J)作为一个简单的门面或抽象,用来服务于各种各样的日志框架,比如java.util.logging.lo ...

  8. slf4j log4j logback log4j2关系详解和相关用法

    来源:slf4j log4j logback关系详解和相关用法https://www.cnblogs.com/Sinte-Beuve/p/5758971.html The Simple Logging ...

  9. 通过slf4j/log4j的MDC/NDC 实现日志追踪

    在分布式系统或者较为复杂的系统中,我们希望可以看到一个客户请求的处理过程所涉及到的所有子系统\模块的处理日志. 由于slf4j/log4j基本是日志记录的标准组件,所以slf4j/log4j成为了我的 ...

随机推荐

  1. 配置Tomcat监听80端口 配置Tomcat虚拟主机 Tomcat日志

    配置Tomcat监听80端口 • vim /usr/local/tomcat/conf/server.xml Connector port=" protocol="HTTP/1.1 ...

  2. C++入门学习

    使用cout和cin,需要包括C++提供的输入输出库.#include <iostream>    标准输入输出头文件 <string>        using namesp ...

  3. selenium 如何处理table

    qi_ling2005  http://jarvi.iteye.com/blog/1477837 andyguo  http://blog.csdn.net/gzh0222/article/detai ...

  4. 【Linux】理解分区

    http://blog.csdn.net/aaronychen/article/details/2270048 主分区逻辑分区设置 http://forum.ubuntu.org.cn/viewtop ...

  5. 英文版Ubuntu18.10安装搜狗输入法过程(图文并茂,亲自尝试!)

    英文版Ubuntu18.10安装搜狗输入法过程 过程比较艰辛,折腾了好长的时间,不过最终还是装好了,特记录一下! 首先去搜狗输入法网址下载Linux版本:https://pinyin.sogou.co ...

  6. C# AES要解密的数据的长度无效

    加密方式  AES-CBC-128 将解密方法改成如下 public string Decrypt(string toDecrypt, string key) { if (string.IsNullO ...

  7. Eclipse------导入项目后出现Java compiler level does not match the version of the installed Java project facet

    报错信息:Java compiler level does not match the version of the installed Java project facet 解决方法: 1.点击工具 ...

  8. Java终止循环体

    编写程序,是先创建一个字符串数组,在使用foreach语句遍历时,如果发现数组中包含字符串“老鹰”则立刻中断循环.再创建一个整数类型的二维数组,使用双层foreach语句循环遍历,当发现第一个小于60 ...

  9. Android实现图片缩放示例

    package com.example.demo; import android.os.Bundle; import android.app.Activity; import android.grap ...

  10. 【NLP】HanLP环境

    1.参考:https://github.com/hankcs/pyhanlp 2.问题: C:\Users\ADMINI~1\AppData\Local\Temp\pip-install-u617cf ...