簡介
簡單日志門面(Simple Logging Facade For Java)?
SLF4J主要是為了給Java日志訪問提供一套標準、規范的API框架,
其主要意義在于提供接口,具體的實現可以交由其他日志框架,如log4j、logback、log4j2。?
對于一般的Java項目而言,日志框架會選擇slf4j-api作為門面,配上具體的實現框架,中間使用橋接器完成橋接。
所以我們可以得出SLF4J最重要的兩個功能就是對于日志框架的綁定以及日志框架的橋接。
slf4j+log4j
依賴
<dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.21</version></dependency><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-log4j12</artifactId><version>1.7.21</version></dependency>
使用入口
Logger logger = LoggerFactory.getLogger(Slf4jAndLog4j.class);logger.info("this is slf4j&log4j test:{}",123);
log4j的配置文件參見:log4j日志框架的使用-CSDN博客
slf4j+logback
依賴
<dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.1.7</version>
</dependency>
使用入口
Logger logger = LoggerFactory.getLogger(Slf4jAndLogback.class);
logger.info("this is slf4j&logback test:{}",123);
logback配置參見:logback日志框架使用-CSDN博客
slf4j+log4j2
依賴
<!--sl4j日志門面--><dependency><groupId>org.slf4j</groupId><artifactId>slf4j-api</artifactId><version>1.7.25</version></dependency><!--log4j適配器--><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-slf4j-impl</artifactId><version>2.12.1</version></dependency><!--log4j2實現--><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.12.1</version></dependency>
使用入口
Logger logger = LoggerFactory.getLogger(Slf4jAndLog4j2.class);
logger.info("this is slf4j&log4j2 test:{}",123);
log4j2的配置參見:log4j2日志框架使用-CSDN博客
實現原理
代碼解析入口:
LoggerFactory.getLogger(Slf4jAndLog4j2.class);
該段代碼會尋找依賴中的日志實現
如何尋找日志依賴?
org.slf4j.LoggerFactory#findPossibleStaticLoggerBinderPathSet方法會讀取依賴中所有的org.slf4j.impl.StaticLoggerBinder類所在的文件路徑
在工作路徑下,依賴下尋找文件名為:org/slf4j/impl/StaticLoggerBinder.class的文件。其實說白一點,就只尋找各個日志框架的橋接引導類org.slf4j.impl.StaticLoggerBinder,如下是各個日志框架實現的橋接截圖:
尋找到對應的日志框架橋接的引導類之后,調用初始化操作完成日志的加載和初始化動作。這就是slf4j門面模式和各日志框架實現的原理
log4j的引導操作截圖如下:
在前面的關于log4j的源碼淺析(log4j日志框架的使用-CSDN博客)中,log4j的初始化LogManager類中完成的。slf4j的橋接器(StaticLoggerBinder)引導完成初始化加載
log4j2的引導操作截圖如下:
在前面的關于log4j2的源碼淺析(log4j2日志框架使用-CSDN博客)中,log4j2的入口是LogManager的靜態代碼塊加載。slf4j的橋接器(StaticLoggerBinder)引導完成初始化加載
logback的引導操作可以翻看前面的文章:logback日志框架使用-CSDN博客
各日志框架性能對比
引用一張log4j2的官方性能壓測數據圖:
log4j2的異步日志性能明顯高于log4j和logback(由于日志框架出現的時間有先后,后面的日志肯定會規避前面日志框架的缺點而繼承其優點)
log4j2全異步日志開啟
1 引入依賴
<dependency><groupId>com.lmax</groupId><artifactId>disruptor</artifactId><version>3.4.2</version>
</dependency>
2 增加啟動參數
-Dlog4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
或者
System.setProperty("Log4jContextSelector", "org.apache.logging.log4j.core.async.AsyncLoggerContextSelector")
@slf4j注解實現原理
平時在使用slf4j門面日志配合其他日志框架時,很少會在類中通過編碼定義Logger對象,而習慣性的使用@slf4j注解完成Logger定義。不知道大家想過沒有,這個注解是如何實現的?
@slf4j注解是由lombok?
依賴引入的,該依賴會將標注了@slf4j的類編程成形如:
private static final Logger log = LoggerFactory.getLogger(Demo2.class);
的一個log對象
源代碼如下:
編譯之后的類: