成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

slf4j 的實(shí)現(xiàn)發(fā)現(xiàn)

Joyven / 496人閱讀

摘要:按照官方的說法,是一個(gè)用于日志系統(tǒng)的簡單,允許最終用戶在部署其應(yīng)用時(shí)使用其所希望的日志系統(tǒng)。這個(gè)方法里就會通過去綁定具體的日志實(shí)現(xiàn)。我們直接看一下中的的源碼實(shí)現(xiàn)首先通過判斷一個(gè)類是否已經(jīng)被加載過。

SLF4J,即簡單日志門面(Simple Logging Facade for Java),不是具體的日志解決方案,而是通過Facade Pattern提供一些Java logging API,它只服務(wù)于各種各樣的日志系統(tǒng)。按照官方的說法,SLF4J是一個(gè)用于日志系統(tǒng)的簡單Facade,允許最終用戶在部署其應(yīng)用時(shí)使用其所希望的日志系統(tǒng)。
實(shí)際上,SLF4J所提供的核心API是一些接口以及一個(gè)LoggerFactory的工廠類。在使用SLF4J的時(shí)候,不需要在代碼中或配置文件中指定你打算使用那個(gè)具體的日志系統(tǒng)。SLF4J提供了統(tǒng)一的記錄日志的接口,只要按照其提供的方法記錄即可,最終日志的格式、記錄級別、輸出方式等通過具體日志系統(tǒng)的配置來實(shí)現(xiàn),因此可以在應(yīng)用中靈活切換日志系統(tǒng)。具體的日志系統(tǒng)可以選用log4j,log4j2,logback等。
1.SLF4J 怎么找到具體的實(shí)現(xiàn)?
SLF4J的實(shí)現(xiàn)是通過org.slf4j.impl.StaticLoggerBinder 來進(jìn)行加載具體的實(shí)現(xiàn)的

org.slf4j.impl.StaticLoggerBinder的代碼實(shí)現(xiàn)(log4j2):

public final class StaticLoggerBinder implements LoggerFactoryBinder {

    /**
     * Declare the version of the SLF4J API this implementation is compiled
     * against. The value of this field is usually modified with each release.
     */
    // to avoid constant folding by the compiler, this field must *not* be final
    public static String REQUESTED_API_VERSION = "1.6"; // !final

    private static final String LOGGER_FACTORY_CLASS_STR = Log4jLoggerFactory.class.getName();

    /**
     * The unique instance of this class.
     */
    private static final StaticLoggerBinder SINGLETON = new StaticLoggerBinder();

    /**
     * The ILoggerFactory instance returned by the {@link #getLoggerFactory}
     * method should always be the same object
     */
    private final ILoggerFactory loggerFactory;

    /**
     * Private constructor to prevent instantiation
     */
    private StaticLoggerBinder() {
        loggerFactory = new Log4jLoggerFactory();
    }

    /**
     * Returns the singleton of this class.
     *
     * @return the StaticLoggerBinder singleton
     */
    public static StaticLoggerBinder getSingleton() {
        return SINGLETON;
    }

    /**
     * Returns the factory.
     * @return the factor.
     */
    @Override
    public ILoggerFactory getLoggerFactory() {
        return loggerFactory;
    }

    /**
     * Returns the class name.
     * @return the class name;
     */
    @Override
    public String getLoggerFactoryClassStr() {
        return LOGGER_FACTORY_CLASS_STR;
    }
}

logback 的實(shí)現(xiàn)也是大同小異,都是實(shí)現(xiàn) LoggerFactoryBinder 接口,然后再實(shí)現(xiàn)里提供ILoggerFactory的實(shí)現(xiàn)類給SLF4J 用來做到日志框架的綁定。

private Logger logger = LoggerFactory.getLogger(DynamicProxy.class);

LoggerFactory.getLogger(DynamicProxy.class) 是靜態(tài)方法,SLF4J 在這里進(jìn)行具體實(shí)現(xiàn)的綁定。

在這里有一塊同步代碼,確保ILoggerFactory 只有一個(gè)。

這個(gè)方法里就會通過 StaticLoggerBinder.getSingleton(); 去綁定具體的日志實(shí)現(xiàn)。
2.當(dāng)項(xiàng)目里同時(shí)存在多個(gè)日志框架(用來實(shí)現(xiàn)SLF4J)的時(shí)候,系統(tǒng)會選擇哪一個(gè)
這個(gè)是通過jvm的類加載機(jī)制來控制的,會選擇classpath 路徑里面出現(xiàn)在前面的哪一個(gè)日志框架

jvm包括三種類加載器:
第一種:bootstrap classloader:加載java的核心類。
第二種:extension classloader:負(fù)責(zé)加載jre的擴(kuò)展目錄中的jar包。
第三種:它負(fù)責(zé)在JVM被啟動時(shí),加載來自在命令java中的-classpath或者java.class.path系統(tǒng)屬性或者?CLASSPATH操作系統(tǒng)屬性所指定的JAR類包和類路徑。

jvm 加載包名和類名相同的類時(shí),先加載classpath中jar路徑放在前面的,包名類名都相同,那jvm沒法區(qū)分了,如果使用ide一般情況下是會提示發(fā)生沖突而報(bào)錯(cuò),若不報(bào)錯(cuò),只有第一個(gè)包被引入(在classpath路徑下排在前面的包),第二個(gè)包會在classloader加載類時(shí)判斷重復(fù)而忽略。

類加載器
虛擬機(jī)設(shè)計(jì)團(tuán)隊(duì)把加載動作放到JVM外部實(shí)現(xiàn),以便讓應(yīng)用程序決定如何獲取所需的類,JVM提供了3種類加載器:
· 啟動類加載器(Bootstrap ClassLoader):負(fù)責(zé)加載 JAVA_HOMElib 目錄中的,或通過-Xbootclasspath參數(shù)指定路徑中的,且被虛擬機(jī)認(rèn)可(按文件名識別,如rt.jar)的類。
· 擴(kuò)展類加載器(Extension ClassLoader):負(fù)責(zé)加載 JAVA_HOMElibext 目錄中的,或通過java.ext.dirs系統(tǒng)變量指定路徑中的類庫。
· 應(yīng)用程序類加載器(Application ClassLoader):負(fù)責(zé)加載用戶路徑(classpath)上的類庫。
JVM通過雙親委派模型進(jìn)行類的加載,當(dāng)然我們也可以通過繼承java.lang.ClassLoader實(shí)現(xiàn)自定義的類加載器。

當(dāng)一個(gè)類加載器收到類加載任務(wù),會先交給其父類加載器去完成,因此最終加載任務(wù)都會傳遞到頂層的啟動類加載器,只有當(dāng)父類加載器無法完成加載任務(wù)時(shí),才會嘗試執(zhí)行加載任務(wù)。
采用雙親委派的一個(gè)好處是比如加載位于rt.jar包中的類java.lang.Object,不管是哪個(gè)加載器加載這個(gè)類,最終都是委托給頂層的啟動類加載器進(jìn)行加載,這樣就保證了使用不同的類加載器最終得到的都是同樣一個(gè)Object對象。
在有些情境中可能會出現(xiàn)要我們自己來實(shí)現(xiàn)一個(gè)類加載器的需求,由于這里涉及的內(nèi)容比較廣泛,我想以后多帶帶寫一篇文章來講述,不過這里我們還是稍微來看一下。我們直接看一下jdk中的ClassLoader的源碼實(shí)現(xiàn):

protected synchronized Class loadClass(String name, boolean resolve)
????????throws ClassNotFoundException {
????// First, check if the class has already been loaded
????Class c = findLoadedClass(name);
????if (c == null) {
????????try {
????????????if (parent != null) {
????????????????c = parent.loadClass(name, false);
????????????} else {
????????????????c = findBootstrapClass0(name);
????????????}
????????} catch (ClassNotFoundException e) {
????????????// If still not found, then invoke findClass in order
????????????// to find the class.
????????????c = findClass(name);
????????}
????}
????if (resolve) {
????????resolveClass(c);
????}
????return c;
}

· 首先通過Class c = findLoadedClass(name);判斷一個(gè)類是否已經(jīng)被加載過。
· 如果沒有被加載過執(zhí)行if (c == null)中的程序,遵循雙親委派的模型,首先會通過遞歸從父加載器開始找,直到父類加載器是Bootstrap ClassLoader為止。
· 最后根據(jù)resolve的值,判斷這個(gè)class是否需要解析。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/76961.html

相關(guān)文章

  • 在云環(huán)境上使用SLF4J對Java程序進(jìn)行日志記錄

    摘要:我開發(fā)了一個(gè)應(yīng)用,部署到云環(huán)境上之后,用測試發(fā)現(xiàn)不能按照我期望的工作,但是返回的消息對我沒有任何幫助。的使用非常簡單,在您的應(yīng)用代碼里將的和導(dǎo)入然后在引用代碼里用獲得實(shí)例然后用進(jìn)行日志記錄。 我開發(fā)了一個(gè)Java應(yīng)用,部署到云環(huán)境上之后,用postman測試發(fā)現(xiàn)不能按照我期望的工作,但是返回的消息對我沒有任何幫助。 showImg(https://segmentfault.com/im...

    TigerChain 評論0 收藏0
  • 聊一聊Java日志之一:slf4j

    摘要:一引言程序員都知道,日志對于一個(gè)應(yīng)用系統(tǒng)來說至關(guān)重要,現(xiàn)在應(yīng)該也沒有無日志的系統(tǒng)了吧。具體的日志實(shí)現(xiàn)還是需要使用不同的日志框架來完成。然后如下使用測試測試測試測試運(yùn)行結(jié)果發(fā)現(xiàn)并沒有打印出日志,這是因?yàn)槿鄙倭伺渲梦募? 一、引言   程序員都知道,日志對于一個(gè)應(yīng)用系統(tǒng)來說至關(guān)重要,現(xiàn)在應(yīng)該也沒有無日志的系統(tǒng)了吧。很多程序員都知道 Log4j,Logback,java.util.loggi...

    church 評論0 收藏0
  • 長文慎入-探索Java并發(fā)編程與高并發(fā)解決方案

    摘要:所有示例代碼請見下載于基本概念并發(fā)同時(shí)擁有兩個(gè)或者多個(gè)線程,如果程序在單核處理器上運(yùn)行多個(gè)線程將交替地?fù)Q入或者換出內(nèi)存這些線程是同時(shí)存在的,每個(gè)線程都處于執(zhí)行過程中的某個(gè)狀態(tài),如果運(yùn)行在多核處理器上此時(shí),程序中的每個(gè)線程都 所有示例代碼,請見/下載于 https://github.com/Wasabi1234... showImg(https://upload-images.jians...

    SimpleTriangle 評論0 收藏0
  • Spring Boot日志框架實(shí)踐

    摘要:概述應(yīng)用中,日志一般分為以下個(gè)級別錯(cuò)誤信息警告信息一般信息調(diào)試信息跟蹤信息使用的作為內(nèi)部的日志框架,其僅僅是一個(gè)日志接口,在實(shí)際應(yīng)用中需要為該接口來指定相應(yīng)的日志實(shí)現(xiàn)。默認(rèn)的日志實(shí)現(xiàn)是,是自帶的日志包,此外當(dāng)然也支持這類很流行的日志實(shí)現(xiàn)。 showImg(https://segmentfault.com/img/remote/1460000014055501); 概述 Java應(yīng)用中...

    inapt 評論0 收藏0
  • 如何配置SLF4J不同日志實(shí)現(xiàn)

    摘要:想要看級別的信息,你需要在啟動時(shí)傳入這個(gè)系統(tǒng)屬性使用與日志現(xiàn)在我們可以試驗(yàn)并更換不同的日志實(shí)現(xiàn),但你的程序代碼可以保持不變。我們要做的是用另一個(gè)流行的日志實(shí)現(xiàn)來替換掉,比如。又一次,我們必須對我們選的每一個(gè)日志實(shí)現(xiàn)做配置。 使用slf4j庫作為你的Java應(yīng)用日志API層有很多好處,這里我會展示一小部分關(guān)于如何使用和配置它的例子。 你可以把slf4j想成一個(gè)Java的接口,然后你需要實(shí)...

    bovenson 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<