亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

java日志門(mén)面之JCL和SLF4J詳解

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

前言

什么時(shí)日志門(mén)面?

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

常見(jiàn)的日志框架及日志門(mén)面

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

日志門(mén)面和日志實(shí)現(xiàn)的關(guān)系

一、JCL

1、JCL簡(jiǎn)介

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

2、快速入門(mén)

jcl依賴(lài)

<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");
    }
}

只導(dǎo)入commons-logging的輸出結(jié)果

  • 此時(shí)沒(méi)有任何第三方日志框架,我們使用的就是jdk自帶的JUL

導(dǎo)入commons-logging并添加log4j依賴(lài)和log4j.properties配置文件輸出結(jié)果

<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>
#配置根節(jié)點(diǎn)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原理

  • 通過(guò)LogFactory動(dòng)態(tài)加載Log實(shí)現(xiàn)類(lèi)
  • Jdk14Logger就是jdk自帶JUL日志框架(因?yàn)镴UL從jdk1.4開(kāi)始提供)
  • SimpleLog是日志門(mén)面JCL自帶日志,功能簡(jiǎn)單一般不用

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

二、SLF4J

1、SLF4J簡(jiǎn)介

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

2、快速入門(mén)

slf4j依賴(lài)

<!--slf4j 核心依賴(lài)-->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.25</version>
</dependency>

<!--slf4j 自帶的簡(jiǎn)單日志實(shí)現(xiàn) -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-simple</artifactId>
    <version>1.7.25</version>
</dependency>
  • slf4j-api只提供api,具體日志實(shí)現(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信息");
    }
}

輸出結(jié)果:

2.1、輸出動(dòng)態(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("學(xué)生信息-姓名:"+name+";年齡:"+age); 字符串拼接,效率低
    // logger.info("學(xué)生信息-姓名:{},年齡:{}",new Object[]{name,age}); 老方式,代碼冗余
    logger.info("學(xué)生信息-姓名:{},年齡:{}", name, age);// 新方式,簡(jiǎn)單
}

輸出結(jié)果:

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("具體錯(cuò)誤是:", e);
    }
}

輸出結(jié)果:

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

使用slf4j綁定日志的流程

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

使用slf4j綁定日志的原理

  • public class StaticLoggerBinder implements LoggerFactoryBinder
  • 這個(gè)類(lèi)負(fù)責(zé)靜態(tài)org.slf4j.LoggerFactory類(lèi)與相應(yīng)的日志實(shí)現(xiàn)ILoggerFactory類(lèi)綁定
  • 只要有這個(gè)類(lèi)就可以實(shí)現(xiàn)slf4j門(mén)面+對(duì)應(yīng)日志實(shí)現(xiàn),包名都是org.slf4j.impl

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

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

依賴(lài)

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

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

導(dǎo)包

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
  • 如果有多個(gè)日志實(shí)現(xiàn)的話,會(huì)出紅色警告,默認(rèn)使用先導(dǎo)入的實(shí)現(xiàn)
  • 無(wú)論使用slf4j自己的slf4j-simple還是logback,導(dǎo)包都不會(huì)變,都用的以上兩個(gè)
@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信息");
}

輸出結(jié)果:

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

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

依賴(lài)

<!--slf4j 核心依賴(lài)-->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.25</version>
</dependency>

<!-- 
導(dǎo)入log4j適配器依賴(lài)
slf4j-log4j12依賴(lài)的slf4j-api,slf4j-api可以不用重復(fù)導(dǎo)入依賴(lài)
 -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.25</version>
</dependency>

導(dǎo)包

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

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

# 配置appender輸出方式:輸出到控制臺(tái)
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

輸出結(jié)果:

與slf4j-simple和logback的實(shí)現(xiàn)原理其實(shí)一樣,都是在相同包下org.slf4j.impl下創(chuàng)建StaticLoggerBinder類(lèi)將slf4j門(mén)面與日志實(shí)現(xiàn)綁定起來(lái)。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、橋接舊的日志框架

橋接解決的問(wèn)題:當(dāng)系統(tǒng)中存在之前的日志API,可以通過(guò)橋接轉(zhuǎn)換到slf4j的實(shí)現(xiàn)

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

4.1、log4j日志重構(gòu)為slf4j+logback的組合

重構(gòu)前

依賴(lài)

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

log4j.properties

#配置根節(jié)點(diǎn)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

導(dǎo)包

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

重構(gòu)后

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

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

總結(jié)

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

相關(guān)文章

  • 詳解Maven optional關(guān)鍵字透徹圖解

    詳解Maven optional關(guān)鍵字透徹圖解

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

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

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

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

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

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

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

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

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

    自己動(dòng)手用Springboot實(shí)現(xiàn)仿百度網(wǎng)盤(pán)的實(shí)踐

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

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

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

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

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

    Java輕松入門(mén)冒泡?選擇?插入?希爾?歸并排序算法

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

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

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

最新評(píng)論