一篇文章带你搞定 Java 日志框架 slf4j

一、门面模式

slf4j是门面模式的典型应用,因此在讲slf4j前,先简单学习下门面模式,

门面模式,其核心为外部与一个子系统的通信必须通过一个统一的外观对象进行,使得子系统更易于使用

用一张图来表示门面模式的结构为:
在这里插入图片描述
门面模式的核心为Facade即门面对象,门面对象核心为几个点:

  • 知道所有子角色的功能和责任
  • 将客户端发来的请求委派到子系统中,没有实际业务逻辑
  • 不参与子系统内业务逻辑的实现

二、为什么要使用 slf4j ?

我们自己的系统中使用了logback这个日志系统
我们的系统使用了 A.jar,A.jar 中使用的日志系统为 log4j
我们的系统又使用了 B.jar,B.jar 中使用的日志系统为 slf4j-simple

这样,我们的系统就不得不同时支持并维护 logback、log4j、slf4j-simple 三种日志框架,非常不便。

解决这个问题的方式就是引入一个适配层,由适配层决定使用哪一种日志系统,而调用端只需要做的事情就是打印日志而不需要关心如何打印日志,slf4j 或者 commons-logging 就是这种适配层,slf4j 是本文研究的对象

从上面的描述,我们必须清楚地知道一点:slf4j只是一个日志标准,并不是日志系统的具体实现

理解这句话非常重要,slf4j只做两件事情:

  • 提供日志接口
  • 提供获取具体日志对象的方法

slf4j-simplelogback都是 slf4j 的具体实现,log4j 并不直接实现 slf4j,但是有专门的一层桥接 slf4j-log4j12 来实现slf4j。

三、如何使用

slf4j 的直接/间接实现有 slf4j-simple、logback、slf4j-log4j12,我们先定义一个 pom.xml,引入相关jar包:

(1)slf4j-api.jar + slf4j-simple.jar
(2)slf4j-api.jar + slf4j-jdk.jar
(3)slf4j-api.jar + slf4j-log4j12.jar + log4j.jar
(4)slf4j-api.jar + logback

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>testSlf4j</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>14</maven.compiler.source>
        <maven.compiler.target>14</maven.compiler.target>
    </properties>

    <dependencies>
        <!--提供日志接口-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.5.6</version>
        </dependency>
        <!-- 1>>>具体实现-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-jdk14</artifactId>
            <version>1.5.6</version>
        </dependency>
        <!-- 2>>>具体实现-->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.12</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.21</version>
        </dependency>
        <!-- 3>>>具体实现-->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>
        <!-- 4>>>具体实现-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>1.7.2</version>
        </dependency>
    </dependencies>
</project>

简单测试:

public class TestLogger {
    public static void main(String[] args) {
        Logger logger = LoggerFactory.getLogger(TestLogger.class);
        logger.error("123");
    }
}

接着我们首先把上面 pom.xml 的具体的四种实现注释掉,即不引入任何slf4j的实现类,运行TestLogger 方法,我们看一下控制台的输出为:

在这里插入图片描述
看到没有任何日志的输出,这验证了我们的观点:slf4j不提供日志的具体实现,只有slf4j是无法打印日志的

接着打开 slf4j-simple 的注释,运行 TestLogger 方法,我们看一下控制台的输出为:
在这里插入图片描述
看到我们只要引入了一个slf4j的具体实现类,即可使用该日志框架输出日志。

最后做一个测验,我们把所有日志打开,运行 TestLogger 方法,控制台输出为:
在这里插入图片描述
和上面的差别是,可以输出日志,但是会输出一些告警日志,提示我们同时引入了多个slf4j的实现,然后选择其中的一个作为我们使用的日志系统。

slf4j 的作用:只要所有代码都使用门面对象 slf4j,我们就不需要关心其具体实现,最终所有地方使用一种具体实现即可,更换、维护都非常方便

同时,SLF4J的日志接口传入的是一个带占位符的字符串,用后面的变量自动替换占位符

public class TestLogger {
    public static void main(String[] args) {
        Logger logger = LoggerFactory.getLogger(TestLogger.class);

        Person person = new Person();
        person.setName("test");
        person.setAge(18);

        logger.info("Set age {} for Person {} ok", person.getAge(), person.getName());
        logger.error("123");
    }
}

在这里插入图片描述

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
内容简介: 设计模式是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性、程序的重用性。 本课程内容定位学习设计原则,学习设计模式的基础。在实际开发过程中,并不是一定要求所有代码都遵循设计原则,我们要考虑人力、时间、成本、质量,不是刻意追求完美,要在适当的场景遵循设计原则,体现的是一种平衡取舍,帮助我们设计出更加优雅的代码结构。本章将详细介绍开闭原则(OCP)、依赖倒置原则(DIP)、单一职责原则(SRP)、接口隔离原则(ISP)、迪米特法则(LoD)、里氏替换原则(LSP)、合成复用原则(CARP)的具体内容。 为什么需要学习这门课程? 你在日常的开发中,会不会也遇到过同样的问题。系统出现问题,不知道问题究竟出在什么位置;当遇到产品需求,总是对代码缝缝补补,不能很快的去解决。而且平时工作中,总喜欢把代码堆在一起,出现问题时,不知道如何下手,工作效率很低,而且自己的能力也得不到提升。而这些都源于一个问题,那就是软件设计没做好。这门课能帮助你很好的认识设计模式,让你的能力得到提升。课程大纲: 为了让大家快速系统了解设计模式知识全貌,我为您总结了思维导图,帮您梳理学习重点,建议收藏!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南淮北安

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值