成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Java日志之Slf4j,Log4J,Logback原理總結

開發 后端
我們Java開發者使用統一的API,而JVM對接各個操作系統。嚴格意義上說slf4j自身并不提供日志具體實現。

 幾乎任何應用,一定是需要日志的。

那么,面對種類繁多的日志框架和配置,我們該何去何從?

[[312023]]

1.前奏:我是在研究mybatis源碼的過程中才意識到需要搞明白日志原理這回事,因為mybatis(和一些其他開源框架,比如rocketmq)都有自己的日志系統,他們在框架內部都使用的是自己的日志API,那么,為什么他們不像我們平常那樣配置一個log4j呢?根本原因我也不太清楚,不過我猜測可能有這么一些理由,這些框架比較老,當初還沒有slf4j這種事實上的標準,另一方面,有一些特殊的定制化的日志。徹底研究清楚mybatis的日志系統之后,個人覺得這一塊設計得不太好,至少今天看來,不太優雅,因為本來一個slf4j就能搞定所有,非得在源碼中加入自己的org.apache.ibatis.logging這個包,里面包含一些適配器,雖然代碼并不復雜,但是有點多此一舉。

2.原理:slf4j是標準,也是門面,他對用戶提供統一的API,而下方對接各個日志框架。這有點類似JVM,我們Java開發者使用統一的API,而JVM對接各個操作系統。嚴格意義上說slf4j自身并不提供日志具體實現。圖片來自:https://www.cnblogs.com/hanszhao/p/9754419.html

 

Java日志之Slf4j,Log4J,logback原理總結

 

3.slf4j采用的是SPI機制,指定一個標準的目錄結構:org.slf4j.impl.StaticLoggerBinder,然第三方的框架都必須存在一個這樣的類,用于和slf4j建立關系,比如slf4j-simple.jar,logback,這兩個直接實現了slf4j的接口,而對于log4j這種則需要一個中間適配器slf4j-log4j12。于是乎,當調用slf4j的Logger logger = LoggerFactory.getLogger(XXX.class)的時候,雖然使用的是slf4j的api,但是真正輸出日志的是具體的日志框架,這樣子做的好處就是,當某一天你希望更換日志框架了,只需要把具體日志框架的jar包替換掉,不需要更改任何一行代碼,就能實現日志框架的切換。

4.slf4j是如何發現具體日志框架的,這就得意于spi機制,前面說每個日志框架都需要存在一個org.slf4j.impl.StaticLoggerBinder類,log4j則是通過中間適配器slf4j-log4j12。當調用LoggerFactory.getLogger的時候,就會去classpath中尋找StaticLoggerBinder這個類,如果不存在或者存在超過1個,那么會報錯,classpath有且只能存在一個StaticLoggerBinder類。

5.分析mybatis的日志框架:mybatis有一套屬于自己的日志系統,日志api是:Log log = LogFactory.getLog(xxx.class),于此同時,封裝了幾個主流的日志框架適配器,包括:SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING,當調用Log log = LogFactory.getLog(xxx.class)時,會初始化眾多適配器中的一個,可以在mybatis的配置文件中通過logImpl指定具體的一個,如果不指定那么默認使用SLF4J,因為這里在LogFactory類中的靜態代碼快第一個就是SLF4J:

  1. static { 
  2.  tryImplementation(LogFactory::useSlf4jLogging); 
  3.  tryImplementation(LogFactory::useCommonsLogging); 
  4.  tryImplementation(LogFactory::useLog4J2Logging); 
  5.  tryImplementation(LogFactory::useLog4JLogging); 
  6.  tryImplementation(LogFactory::useJdkLogging); 
  7.  tryImplementation(LogFactory::useNoLogging); 
  8.  } 

假設使用默認配置,那么就會初始化Slf4jImpl類,這個類內部有個代理log,這個代理log就是Logger logger = LoggerFactory.getLogger(clazz),這就回歸到slf4j的標準使用方式上面來了,mybatis打印日志,其實就是代理對象在打印,而代理對象就是classpath中配置的具體日志框架。

6.分析log4j是如何與slf4j整合的:前面說到,要使用log4j就必須引入slf4j-log4j12這個jar包,而這個jar包中同樣存在一個StaticLoggerBinder類,當我們調用LoggerFactory.getLogger(clazz)的時候,同樣是初始化StaticLoggerBinder,然后調用利用ILoggerFactory創建一個log4j的Logger實例,代碼如下:

  1. public class Log4jLoggerFactory implements ILoggerFactory { 
  2.   
  3.  // keyname (String), value: a Log4jLoggerAdapter; 
  4.  ConcurrentMap<String, Logger> loggerMap; 
  5.   
  6.   
  7.  public Log4jLoggerFactory() { 
  8.  loggerMap = new ConcurrentHashMap<String, Logger>(); 
  9.  } 
  10.   
  11.  /* 
  12.  * (non-Javadoc) 
  13.  *  
  14.  * @see org.slf4j.ILoggerFactory#getLogger(java.lang.String) 
  15.  */ 
  16.  public Logger getLogger(String name) { 
  17.  Logger slf4jLogger = loggerMap.get(name); 
  18.  if (slf4jLogger != null) { 
  19.  return slf4jLogger; 
  20.  } else { 
  21.  org.apache.log4j.Logger log4jLogger; 
  22.  if(name.equalsIgnoreCase(Logger.ROOT_LOGGER_NAME)) 
  23.  log4jLogger = LogManager.getRootLogger(); 
  24.  else 
  25.  log4jLogger = LogManager.getLogger(name); 
  26.   
  27.  Logger newInstance = new Log4jLoggerAdapter(log4jLogger); 
  28.  Logger oldInstance = loggerMap.putIfAbsent(name, newInstance); 
  29.  return oldInstance == null ? newInstance : oldInstance; 
  30.  } 
  31.  } 
  32.  } 

最關鍵的一行就是第27行Logger newInstance = new Log4jLoggerAdapter(log4jLogger),slf4j的Logger對象實際上是一個log4j的適配器對象(也是代理對象),當slf4j調用比如debug方法的時候,實際上是代理對象(也就是真實的log4j對象)在調用debug方法。

責任編輯:武曉燕 來源: 今日頭條
相關推薦

2016-10-21 13:10:18

javalog4jslf4j

2013-02-20 09:42:34

JavaLogbackSLF4J

2023-10-28 16:19:18

Android日志

2024-03-01 16:52:02

SLF4J日志框架

2020-11-04 12:33:08

Log4j 2日志Logback

2023-01-11 21:22:32

Java服務器

2022-12-30 08:31:27

MDC查詢日志

2022-05-12 11:38:26

Java日志Slf4j

2023-10-07 10:08:54

2021-03-15 18:47:25

日志開發源碼

2021-06-03 10:58:16

logbacklog4jJava

2009-07-08 14:33:46

Java日志框架Log4J

2025-01-14 01:00:00

日志接口Log4j

2021-08-02 15:40:20

Java日志工具

2022-03-25 13:42:15

Log4j漏洞網絡安全

2022-02-13 16:18:57

JetBrainsIntelliJLog4j

2022-02-15 17:51:38

Log4j漏洞網絡安全

2020-10-27 08:24:45

阿里巴巴SLF4J

2013-05-21 10:58:43

Log4jActiveMQSpring

2021-12-14 23:44:26

漏洞Log4j項目
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产精品久久久久久久久久久免费看 | 国产午夜亚洲精品不卡 | 在线不卡视频 | 黄视频在线网站 | 久久国产日韩欧美 | 午夜精品一区二区三区在线观看 | 国产精品久久久久久久模特 | h网站在线观看 | 国产综合精品一区二区三区 | 久久这里只有精品首页 | 亚洲国产精品久久久久秋霞不卡 | 在线亚洲欧美 | 波多野结衣精品在线 | 日韩免费 | 欧美日韩在线观看视频 | 黄网站免费在线观看 | 中文字幕一页二页 | 国产精品久久久久久久久久免费看 | 久国产精品 | 久久久久久亚洲精品不卡 | 欧美精品久久久久久久久久 | 亚洲成av人片在线观看无码 | 黄色精品 | 国产精品日日做人人爱 | 一区二区在线 | 五月激情六月婷婷 | 成人精品一区 | 国产一区二区三区在线 | 99视频在线免费观看 | 99成人免费视频 | 一二三四在线视频观看社区 | 欧美xxxⅹ性欧美大片 | 中文字幕在线看人 | 欧美日韩精品在线免费观看 | 国产精品久久久久久久午夜片 | 欧美精品国产精品 | 亚洲视频在线观看免费 | 久久蜜桃av | 久久成人综合 | 国产精品日韩欧美一区二区三区 | 亚洲永久 |