欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

java日志門面之JCL和SLF4J詳解

 更新時間:2024年10月23日 09:20:29   作者:冬天vs不冷  
這篇文章主要給大家介紹了關于java日志門面之JCL和SLF4J的相關資料,在系統(tǒng)開發(fā)過程中日志框架的選擇與更換是一大挑戰(zhàn),日志門面的概念,如JCL和SLF4J,允許開發(fā)者面向接口編程,文中介紹的非常詳細,需要的朋友可以參考下

前言

什么時日志門面?

隨著系統(tǒng)開發(fā)的進行,可能會更新不同的日志框架,造成當前系統(tǒng)中存在不同的日志依賴,讓我們難以統(tǒng)一的管理和控制。借鑒JDBC的思想,為日志系統(tǒng)也提供一套門面,那么我們就可以面向這些接口規(guī)范來開發(fā),避免了直接依賴具體的日志框架。這樣我們的系統(tǒng)在日志中,就存在了日志的門面和日志的實現(xiàn)。

常見的日志框架及日志門面

  • 常見日志門面:JCL、slf4j
  • 常見日志實現(xiàn):JUL、log4j、logback、log4j2
  • 框架誕生順序:log4j --> JUL --> JCL --> slf4j --> logback --> log4j2

日志門面和日志實現(xiàn)的關系

一、JCL

1、JCL簡介

  • 全稱為Jakarta Commons Logging,是Apache提供的一個通用日志API
  • common-logging會通過動態(tài)查找的機制,在程序運行時自動找出log4j,或者jdk自帶的jul
  • 使用它的好處就是,代碼依賴是common-logging而非log4j的API, 避免了和具體的日志API直接耦合,在有必要時,可以更改日志實現(xiàn)的第三方庫(不改變代碼,只修改依賴
  • JCL有兩個基本的抽象類:Log(日志記錄器),LogFactory(日志工廠負責創(chuàng)建Log實例)

2、快速入門

jcl依賴

<dependency>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
    <version>1.2</version>
</dependency>
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class JCLTest {
    @Test
    public void test01() {
        Log log = LogFactory.getLog(JCLTest.class);
        log.info("info");
    }
}

只導入commons-logging的輸出結果

  • 此時沒有任何第三方日志框架,我們使用的就是jdk自帶的JUL

導入commons-logging并添加log4j依賴和log4j.properties配置文件輸出結果

<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>
#配置根節(jié)點logger
log4j.rootLogger=info,console

log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%-10p] [%t] [%d{yyyy-MM-dd HH:mm:ss:SSS}] [%l] %m%n

3、 JCL原理

  • 通過LogFactory動態(tài)加載Log實現(xiàn)類
  • Jdk14Logger就是jdk自帶JUL日志框架(因為JUL從jdk1.4開始提供)
  • SimpleLog是日志門面JCL自帶日志,功能簡單一般不用

  • 日志門面創(chuàng)建公共接口org.apache.commons.logging.Log
  • 日志實現(xiàn)類Logger實現(xiàn)接口Log,這樣對外暴露的Log不變,只需要動態(tài)加載不同的Logger
  • 如果只導入JCL門面,不導入其他日志實現(xiàn),那么日志實現(xiàn)為jdk自帶JUL
  • 如果導入JCL門面,并導入log4j依賴,那么日志實現(xiàn)為log4j,log4j優(yōu)先級最高

二、SLF4J

1、SLF4J簡介

  • 簡單日志門面(Simple Logging Facade For Java) SLF4J主要是為了給Java日志訪問提供一套標準、規(guī)范的API框架
  • 主要意義在于提供接口,具體的實現(xiàn)可以交由其他日志框架,例如log4j和logback等
  • slf4j自己也提供了功能較為簡單的實現(xiàn),但是一般很少用到
  • SLF4J最重要的兩個功能就是對于日志框架的綁定以及日志框架的橋接

2、快速入門

slf4j依賴

<!--slf4j 核心依賴-->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.25</version>
</dependency>

<!--slf4j 自帶的簡單日志實現(xiàn) -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-simple</artifactId>
    <version>1.7.25</version>
</dependency>
  • slf4j-api只提供api,具體日志實現(xiàn)由slf4j-simple提供
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class SLF4JTest {
    @Test
    public void test01(){
        Logger logger = LoggerFactory.getLogger(SLF4JTest.class);
        logger.trace("trace信息");
        logger.debug("debug信息");
        logger.info("info信息");
        logger.warn("warn信息");
        logger.error("error信息");
    }
}

輸出結果:

2.1、輸出動態(tài)信息

  • Logger方法:public void info(String format, Object... arguments);
@Test
public void test02() {
    Logger logger = LoggerFactory.getLogger(SLF4JTest.class);
    String name = "zs";
    int age = 23;
    // logger.info("學生信息-姓名:"+name+";年齡:"+age); 字符串拼接,效率低
    // logger.info("學生信息-姓名:{},年齡:{}",new Object[]{name,age}); 老方式,代碼冗余
    logger.info("學生信息-姓名:{},年齡:{}", name, age);// 新方式,簡單
}

輸出結果:

2.2、異常信息的處理

  • Logger方法:public void info(String msg, Throwable t);
@Test
public void test03() {
    Logger logger = LoggerFactory.getLogger(SLF4JTest.class);
    try {
        Class.forName("aaa");
    } catch (ClassNotFoundException e) {
        // 打印棧追蹤信息
        // e.printStackTrace();
        logger.info("具體錯誤是:", e);
    }
}

輸出結果:

3、綁定日志的實現(xiàn)

使用slf4j綁定日志的流程

  • 添加slf4j-api的依賴
  • 使用slf4j的API在項目中進行統(tǒng)一的日志記錄
  • 綁定具體的日志實現(xiàn)框架
    • 綁定已經(jīng)實現(xiàn)了slf4j的日志框架,直接添加對應依賴
    • 綁定沒有實現(xiàn)slf4j的日志框架,先添加日志的適配器,再添加實現(xiàn)類的依賴
  • slf4j有且僅有一個日志實現(xiàn)框架的綁定(如果出現(xiàn)多個默認使用第一個依賴日志實現(xiàn))

使用slf4j綁定日志的原理

  • public class StaticLoggerBinder implements LoggerFactoryBinder
  • 這個類負責靜態(tài)org.slf4j.LoggerFactory類與相應的日志實現(xiàn)ILoggerFactory類綁定
  • 只要有這個類就可以實現(xiàn)slf4j門面+對應日志實現(xiàn),包名都是org.slf4j.impl

3.1、slf4j實現(xiàn)slf4j-simple和logback

slf4j-simple和logback都是slf4j門面出現(xiàn)后才有的日志實現(xiàn),所以這兩生來就有自己的StaticLoggerBinder類。

依賴

<!--slf4j 核心依賴-->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.25</version>
</dependency>
        
<!-- logback依賴 -->
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.3</version>
</dependency>

<!--slf4j 自帶的簡單日志實現(xiàn) -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-simple</artifactId>
    <version>1.7.25</version>
</dependency>

導包

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
  • 如果有多個日志實現(xiàn)的話,會出紅色警告,默認使用先導入的實現(xiàn)
  • 無論使用slf4j自己的slf4j-simple還是logback,導包都不會變,都用的以上兩個
@Test
public void test04(){
    Logger logger = LoggerFactory.getLogger(SLF4JTest.class);
    logger.trace("trace信息");
    logger.debug("debug信息");
    logger.info("info信息");
    logger.warn("warn信息");
    logger.error("error信息");
}

輸出結果:

3.2、slf4j綁定適配器實現(xiàn)log4j

  • 由于log4j是在slf4j之前出品的日志框架實現(xiàn),所以并沒有遵循slf4j的API規(guī)范
  • 之前集成的logback,是slf4j之后出品的日志框架實現(xiàn),就是按照slf4j的標準指定的API,所以我們導入依賴就能用
  • 如果想要使用slf4j門面,需要綁定一個適配器slf4j-log4j12

依賴

<!--slf4j 核心依賴-->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.25</version>
</dependency>

<!-- 
導入log4j適配器依賴
slf4j-log4j12依賴的slf4j-api,slf4j-api可以不用重復導入依賴
 -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.25</version>
</dependency>

導包

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Test
public void test05(){
    Logger logger = LoggerFactory.getLogger(SLF4JTest.class);
    logger.trace("trace信息");
    logger.debug("debug信息");
    logger.info("info信息");
    logger.warn("warn信息");
    logger.error("error信息");
}

log4j.properties

#指定日志的輸出級別與輸出端
log4j.rootLogger=info,console

# 配置appender輸出方式:輸出到控制臺
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%-10p] [%t] [%d{yyyy-MM-dd HH:mm:ss:SSS}] [%l] %m%n

輸出結果:

與slf4j-simple和logback的實現(xiàn)原理其實一樣,都是在相同包下org.slf4j.impl下創(chuàng)建StaticLoggerBinder類將slf4j門面與日志實現(xiàn)綁定起來。log4j需要適配器slf4j-log4j12,JUL需要適配器slf4j-jdk14

3.2、@Slf4j注解

  • 源代碼
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class LogTest {
    @Test
    public void test() {
        log.info("hello world");
    }
}
  • 編譯后class

4、橋接舊的日志框架

橋接解決的問題:當系統(tǒng)中存在之前的日志API,可以通過橋接轉換到slf4j的實現(xiàn)

  • 先去除之前老的日志框架的依賴
  • 添加SLF4J提供的橋接組件
  • 為項目添加SLF4J的具體實現(xiàn)

4.1、log4j日志重構為slf4j+logback的組合

重構前

依賴

<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

log4j.properties

#配置根節(jié)點logger
log4j.rootLogger=trace,console

log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.conversionPattern=[%-10p]%r %c%t%d{yyyy-MM-dd HH:mm:ss:SSS} %m%n

導包

import org.apache.log4j.Logger;
@Test
public void test07(){
    Logger logger = Logger.getLogger(Log4jTest.class);
    logger.info("info信息");
}
  • 查看Logger類源碼,屬于log4j包下的類

重構后

  • 依賴:刪除log4j依賴,添加slf4j提供的橋接組件和logback依賴
<!-- log4j相關的橋接器 -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>log4j-over-slf4j</artifactId>
    <version>1.7.25</version>
</dependency>
<!-- logback依賴 -->
<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.2.3</version>
</dependency>
  • 導包:依然不變
import org.apache.log4j.Logger;
@Test
public void test08(){
    Logger logger = Logger.getLogger(Log4jTest.class);
    logger.info("info信息");
}
  • 查看Logger類源碼,屬于log4j-over-slf4j包下的類

如此操作,看上去依賴還是org.apache.log4j.Logger,實際已不再是log4j包下的類,日志實現(xiàn)也變成了slf4j門面可以隨意搭配的方式了。

總結

到此這篇關于java日志門面之JCL和SLF4J詳解的文章就介紹到這了,更多相關java日志JCL和SLF4J內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • 詳解Maven optional關鍵字透徹圖解

    詳解Maven optional關鍵字透徹圖解

    這篇文章主要介紹了詳解Maven optional關鍵字透徹圖解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2019-11-11
  • Spring Boot與Kotlin 整合全文搜索引擎Elasticsearch的示例代碼

    Spring Boot與Kotlin 整合全文搜索引擎Elasticsearch的示例代碼

    本篇文章主要介紹了Spring Boot與Kotlin 整合全文搜索引擎Elasticsearch的示例代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • Java二叉搜索樹遍歷操作詳解【前序、中序、后序、層次、廣度優(yōu)先遍歷】

    Java二叉搜索樹遍歷操作詳解【前序、中序、后序、層次、廣度優(yōu)先遍歷】

    這篇文章主要介紹了Java二叉搜索樹遍歷操作,結合實例形式詳細分析了Java二叉搜索樹前序、中序、后序、層次、廣度優(yōu)先遍歷等相關原理與操作技巧,需要的朋友可以參考下
    2020-03-03
  • Java實現(xiàn)合并多個升序鏈表

    Java實現(xiàn)合并多個升序鏈表

    本文主要介紹了Java實現(xiàn)合并多個升序鏈表,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-04-04
  • Java實現(xiàn)多線程文件下載的代碼示例

    Java實現(xiàn)多線程文件下載的代碼示例

    本篇文章主要介紹了Java實現(xiàn)多線程下載的代碼示例,Java多線程可以充分利用CPU的資源,具有一定的參考價值,感興趣的小伙伴們可以參考一下。
    2017-02-02
  • 自己動手用Springboot實現(xiàn)仿百度網(wǎng)盤的實踐

    自己動手用Springboot實現(xiàn)仿百度網(wǎng)盤的實踐

    本項目基于Springboot開發(fā)實現(xiàn),前端采用BootStrap開發(fā)實現(xiàn),模仿百度網(wǎng)盤實現(xiàn)相關功能,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • SpringBoot整合RocketMQ實現(xiàn)發(fā)送同步消息

    SpringBoot整合RocketMQ實現(xiàn)發(fā)送同步消息

    RocketMQ 是一款開源的分布式消息中間件,由阿里巴巴開源,它具有高可用性、高性能、低延遲等特點,廣泛應用于阿里巴巴集團內(nèi)部以及眾多外部企業(yè)的業(yè)務系統(tǒng)中,本文給大家介紹了SpringBoot整合RocketMQ實現(xiàn)發(fā)送同步消息,需要的朋友可以參考下
    2024-04-04
  • Java實現(xiàn)分解任意輸入數(shù)的質(zhì)因數(shù)算法示例

    Java實現(xiàn)分解任意輸入數(shù)的質(zhì)因數(shù)算法示例

    這篇文章主要介紹了Java實現(xiàn)分解任意輸入數(shù)的質(zhì)因數(shù)算法,涉及java數(shù)學運算相關操作技巧,需要的朋友可以參考下
    2017-10-10
  • Java輕松入門冒泡?選擇?插入?希爾?歸并排序算法

    Java輕松入門冒泡?選擇?插入?希爾?歸并排序算法

    這篇文章主要介紹了Java常用的排序算法及代碼實現(xiàn),在Java開發(fā)中,對排序的應用需要熟練的掌握,這樣才能夠確保Java學習時候能夠有扎實的基礎能力。那Java有哪些排序算法呢?本文小編就來詳細說說Java常見的排序算法,需要的朋友可以參考一下
    2022-02-02
  • Java TCP協(xié)議通信超詳細講解

    Java TCP協(xié)議通信超詳細講解

    TCP/IP是一種面向連接的、可靠的、基于字節(jié)流的傳輸層通信協(xié)議,它會保證數(shù)據(jù)不丟包、不亂序。TCP全名是Transmission Control Protocol,它是位于網(wǎng)絡OSI模型中的第四層
    2022-09-09

最新評論