一、概述

SLF4J = Simple Logging Facade for Java.
     author: Ceki Gülcü
     SLF4J,即简单日志门面(Simple Logging Facade for Java),不是具体的日志解决方案,而是通过Facade Pattern提供一些Java logging API,它只服务于各种各样的日志系统。按照官方的说法,SLF4J是一个用于日志系统的简单Facade,允许最终用户在部署其应用时使用其所希望的日志系统。作者创建SLF4J的目的是为了替代Jakarta Commons-Logging。

1.1、POM依赖

基础门面

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

桥接包

slfj-log4j12.jar (表示桥接 log4j)
slf4j-jdk14.jar(表示桥接jdk Looging)
sIf4j-jcl.jar(表示桥接 jcl)
log4j-slf4j-impl(表示桥接log4j2)
logback-classic(表示桥接 logback)

1.2、java代码

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
//省略
Logger logger = LoggerFactory.getLogger(Test.class);
// 省略
logger.info("info");

在代码中,并不会出现具体日志框架的api。程序根据classpath中的桥接器类型,和日志框架类型,判断出logger.info应该以什么框架输出!注意了,如果classpath中不小心引了两个桥接器,那会直接报错的!

二、详解  

实际上,SLF4J所提供的核心API是一些接口以及一个LoggerFactory的工厂类。在使用SLF4J的时候,不需要在代码中或配置文件中指定你打算使用那个具体的日志系统。SLF4J提供了统一的记录日志的接口,只要按照其提供的方法记录即可,最终日志的格式、记录级别、输出方式等通过具体日志系统的配置来实现,因此可以在应用中灵活切换日志系统。
     那么什么时候使用SLF4J比较合适呢?
     如果你开发的是类库或者嵌入式组件,那么就应该考虑采用SLF4J,因为不可能影响最终用户选择哪种日志系统。在另一方面,如果是一个简单或者独立的应用,确定只有一种日志系统,那么就没有使用SLF4J的必要。假设你打算将你使用log4j的产品卖给要求使用JDK 1.4 Logging的用户时,面对成千上万的log4j调用的修改,相信这绝对不是一件轻松的事情。但是如果开始便使用SLF4J,那么这种转换将是非常轻松的事情。

  log4j的作者觉得jcl不好用,自己又写了一个新的接口api,那么就是slf4j。关于slf4j的集成图如下所示

  

  如图所示,应用调了sl4j-api,即日志门面接口。日志门面接口本身通常并没有实际的日志输出能力,它底层还是需要去调用具体的日志框架API的,也就是实际上它需要跟具体的日志框架结合使用。由于具体日志框架比较多,而且互相也大都不兼容,日志门面接口要想实现与任意日志框架结合可能需要对应的桥接器,上图红框中的组件即是对应的各种桥接器!

  使用SLF4J时,如果你需要使用某一种日志实现,那么你选择相对应的SLF4J的桥接包即可。比如使用log4j日志组件,就选slf4j-log4j12桥接包,业务中就可以使用log4j进行底层日志输出。

  SLF4J提供的桥接包:
    • slfj-log4j12.jar (表示桥接 log4j)
    • slf4j-jdk14.jar(表示桥接jdk Looging)
    • sIf4j-jcl.jar(表示桥接 jcl)
    • log4j-slf4j-impl(表示桥接log4j2)
    • logback-classic(表示桥接 logback)

  logback是slf4j-api的天然实现,不需要桥接包就可以使用。与commons loging(JCL)不同的是其采用在classPath加入桥接jar包来表示具体采用哪种实现(静态绑定)

2.1、一个项目,一个模块用log4j,另一个模块用slf4j+log4j2,如何统一输出

  这种情况很常见。因为不懂底层的日志原理,日志文件里头既有log4j.properties,又有log4j2.xml,各种API混用,还有人用着jul的API,这里主要用slf4j的适配器,slf4j提供了各种各样的适配器,用来将某种日志框架委托给slf4j。其最明显的集成工作方式有如下:

    

  进行选择填空,将我们的案例里的条件填入,显然应该选log4j-over-slf4j(表示桥接log4j2)适配器,就变成下面这张图

    

  就可以实现日志统一为log4j2来输出!

  说明:根据适配器工作原理的不同,被适配的日志框架并不是一定要删除!以上图为例,log4j这个日志框架删不删都可以,你只要能保证log4j的加载顺序在log4j-over-slf4j后即可。因为log4j-over-slf4j这个适配器的工作原理是,内部提供了和log4j一模一样的api接口,因此你在程序中调用log4j的api的时候,你必须想办法让其走适配器的api。如果你删了log4j这个框架,那你程序里肯定是走log4j-over-slf4j这个组件里的api。如果不删log4j,只要保证其在classpth里的顺序比log4j前即可!

2.2、让spring以log4j2的形式输出

  spring默认使用的是jcl输出日志,由于你此时并没有引入Log4j的日志框架,jcl会以jul做为日志框架。此时集成图如下

    

  而你的应用中,采用了slf4j+log4j-core,即log4j2进行日志记录,那么此时集成图如下

    

  方案一:走jcl-over-slf4j适配器

    

    在这种方案下,spring框架中遇到日志输出的语句,就会如上图红线流程一样,最终以log4J2的形式输出

  方案二、走jul-to-slf4j适配器

    

  这种情况下,记得在代码中执行

SLF4JBridgeHandler.removeHandlersForRootLogger();
SLF4JBridgeHandler.install();

  这样jul-to-slf4j适配器才能正常工作

2.3、死循环

  假设,我们在应用中调用了sl4j-api,但是呢,你引了四个jar包,slf4j-api-xx.jar,slf4j-log4j12-xx.jar,log4j-xx.jar,log4j-over-slf4j-xx.jar,于是你就会出现如下尴尬的场面

    

  如上图所示,在这种情况下,你调用了slf4j-api,就会陷入死循环中!slf4j-api去调了slf4j-log4j12,slf4j-log4j12又去调用了log4j,log4j去调用了log4j-over-slf4j。最终,log4j-over-slf4j又调了slf4j-api,陷入死循环!

依赖分析:Java-idea-常用技巧-转maven,解决包依赖冲突

005-log-slf4j的更多相关文章

  1. Java 写 Log

    . 一个最基本的例子 使用Logging框架写Log基本上就三个步骤 引入loggerg类和logger工厂类 声明logger 记录日志 下面看一个例子 //1. 引入slf4j接口的Logger和 ...

  2. 【Java EE 学习 24 下】【注解在数据库开发中的使用】【反射+注解+动态代理在事务中的应用service层】

    一.使用注解可以解决JavaBean和数据库中表名不一致.字段名不一致.字段数量不一致的问题. 1.Sun公司给jdbc提供的注解 @Table.@Column.@Id.@OneToMany.@One ...

  3. Spring+SpringMVC+MyBatis+LogBack+C3P0+Maven+Git小结(转)

    摘要 出于兴趣,想要搭建一个自己的小站点,目前正在积极的准备环境,利用Spring+SpringMVC+MyBatis+LogBack+C3P0+Maven+Git,这里总结下最近遇到的一些问题及解决 ...

  4. maven工程打包出现Test相关的错误

    ----------------------------------------------------- T E S T S ------------------------------------ ...

  5. kafka2.9.2的伪分布式集群安装和demo(java api)测试

    目录: 一.什么是kafka? 二.kafka的官方网站在哪里? 三.在哪里下载?需要哪些组件的支持? 四.如何安装? 五.FAQ 六.扩展阅读   一.什么是kafka? kafka是LinkedI ...

  6. ubuntu12.04+kafka2.9.2+zookeeper3.4.5的伪分布式集群安装和demo(java api)测试

    博文作者:迦壹 博客地址:http://idoall.org/home.php?mod=space&uid=1&do=blog&id=547 转载声明:可以转载, 但必须以超链 ...

  7. 如何有效地记录 Java SQL 日志?

    在常规项目的开发中可能最容易出问题的地方就在于对数据库的处理了,在大部分的环境下,我们对数据库的操作都是使用流行的框架,比如 Hibernate . MyBatis 等.由于各种原因,我们有时会想知道 ...

  8. 异常:Caused by: java.lang.NoClassDefFoundError: Could not initialize class net.sf.log4jdbc.Properties

    参考文章: 使用Log4jdbc-log4j2监听MyBatis中运行的SQL和Connection 使用 log4jdbc格式化输出SQL,maven配置如下: <dependency> ...

  9. 如何有效地记录 Java SQL 日志(转)

    在常规项目的开发中可能最容易出问题的地方就在于对数据库的处理了,在大部分的环境下,我们对数据库的操作都是使用流行的框架,比如 Hibernate . MyBatis 等.由于各种原因,我们有时会想知道 ...

  10. Hadoop生态圈-Flume的主流source源配置

    Hadoop生态圈-Flume的主流source源配置 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 本篇博客只是配置的是Flume主流的Source,想要了解更详细的配置信息请参 ...

随机推荐

  1. Image Processing and Analysis_15_Image Registration:HAIRIS: A Method for Automatic Image Registration Through Histogram-Based Image Segmentation——2011

    此主要讨论图像处理与分析.虽然计算机视觉部分的有些内容比如特 征提取等也可以归结到图像分析中来,但鉴于它们与计算机视觉的紧密联系,以 及它们的出处,没有把它们纳入到图像处理与分析中来.同样,这里面也有 ...

  2. 使用pyinstaller打包使用cx_Oracle模块的程序出现The specified module could not be found的问题

    pyinstaller看起来并不会将动态链接库自动打包,所以我们需要告诉pyinstaller要打包哪些动态链接库,步骤如下(假设python文件名为 oracletest.py): 1. 使用pyi ...

  3. 2018 CERC 混合博弈

    N堆石子 先手最多拿A个 后手最多拿B个 每次都至少要拿一个 谁先取完谁赢 如果A和B相等直接就是一个bash博弈 如果一个石堆的石子数少于min(A,B) 则是个nim游戏 我们先讨论只有N=1且A ...

  4. springboot中使用cache和redis

    知识点:springboot中使用cache和redis (1)springboot中,整合了cache,我们只需要,在入口类上加 @EnableCaching 即可开启缓存 例如:在service层 ...

  5. waitpid()

    waitpid() pid_t waitpid(pid_t pid, int *status, int options); 参数: pid>0 只等待进程ID等于pid的子进程,不管其它已经有多 ...

  6. django安装好之后,django-admin仍然不能使用的问题

    我使用的是python3,python3不能找到django的正确位置.需要下面这样才能正确建立mysite python3 /usr/lib/python2./site-packages/djang ...

  7. 3、获取Class对象的三种方式

    3.获取Class对象的三种方式 要想对字节码文件进行解刨,必须要有字节码文件对象 Object类中的getClass方法 通过对象静态属性 .class来获取对应的Class对象 只要通过给定类的字 ...

  8. Oracle 后台进程(一)简介

    一.什么是Oracle数据库后台进程 为了时系统性能最好并能够协调多个用户,多进程系统使用了一些附加进程,成为后台进程. 在许多操作系统中,后台进程是在实例启动时自动建立的.一个Oracle实例可以包 ...

  9. PC端使用program來CHGUSRPRF

    執行CHGUSRPRF命令需要*SECADM 權限,但通常Security部門不允許Grant這個這麼大的權限,爲了達到目的,改用下面的方法 1. Create CL program 注意裏面一定要用 ...

  10. webservice应用+建议不用webservice

    webservice应用 1.分布式应用的集成(应用程序之间的集成) 2.软件重用 将一个软件的功能以webservice方式暴露出来,达到软件重用.例如上边分析天气预报,将天气查询功能以webser ...