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. 【Web API系列教程】3.3 — 实战:处理数据(建立数据库)

    前言 在本部分中,你将在EF上使用Code First Migration来用測试数据建立数据库. 在Tools文件夹下选择Library Package Manager,然后选择Package Ma ...

  2. OSG 坑爹的Android example

    本人3D编程方面超级菜鸟,因为项目需要,接触了一些Open Scene Graph(OSG)引擎的相关编程工作.首先我得承认,OSG这个引擎超级牛,无论是渲染效果和效率,都没的说,很棒.但是,OSG提 ...

  3. CentOS6.5下安装iRedMail中需要解决的问题

    iRedMail是个专门用于Redhat/CentOS下的企业Mail服务集成安装软件包,本来只要有干净的系统就可以轻松安装,无奈国内网络状况和墙头众多,安装中也有很多问题需要解决,下面记录的都是我安 ...

  4. 页面 JavaScript 存在多个同名方法的调用分析

    在 JavaScript 中,不存在方法重载的概念,方法重载指的是可以定义不同类型的参数和参数个数的同名方法,然后可以按需调用. 如需实现按参数个数的不同去执行不同的方法主体,正确的做法是通过定义一个 ...

  5. MyBatis的深入原理分析之1-架构设计以及实例分析

    MyBatis是目前非常流行的ORM框架,它的功能很强大,然而其实现却比较简单.优雅.本文主要讲述MyBatis的架构设计思路,并且讨论MyBatis的几个核心部件,然后结合一个select查询实例, ...

  6. 通过expect免自动输入密码登陆远程服务器

    通过expect免自动输入密码登陆远程服务器 1.前提必须已经安装expect 2.新建login.sh,文件内容如下 #!/usr/bin/expect -f spawn ssh root@140. ...

  7. 4. Beego 框架之cookie与session

    what is cookie? cookie是存储在客户端的,用于标识客户身份的! what is session session 是存储在服务端,也是用于客户身份标识,用于跟踪用户会话. BeeGo ...

  8. debian、ubuntu:使用apt包管理器可能存在的问题! 让新手望而却步!

    apt包管理器说好真好,说不好真不好. 最近在debian9.ubuntu18.04上安装oracle 10g 玩. 怎么都准备不好安装环境.原因就是i386构架体系的deb包总安装不正确! baid ...

  9. 如何在Linux系统中安装VMware

    首先打开vmware官网的下载链接:https://my.vmware.com/web/vmware/info/slug/desktop_end_user_computing/vmware_works ...

  10. JS去除字符串左右两端的空格

    去除字符串左右两端的空格,在vbscript里面可以轻松地使用 trim.ltrim 或 rtrim,但在js中却没有这3个内置方法,需要手工编写.下面的实现方法是用到了正则表达式,效率不错,并把这三 ...