国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - MyBatis源碼分析之日志logging詳解

MyBatis源碼分析之日志logging詳解

2021-07-18 15:46魏晉秋 Java教程

這篇文章主要給大家介紹了關于MyBatis源碼分析之日志logging的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧

前言

本文介紹個人對 logging 包下源碼的理解。分享出來供大家參考學習,下面話不多說了,來一起看看詳細的介紹吧

logging 配置加載

我們先從日志的配置加載開始閱讀, mybatis 的各項配置的加載過程都可以從 xmlconfigbuilder 類中找到,我們定位到該類下的日志加載方法 loadcustomlogimpl:

?
1
2
3
4
5
6
7
8
private void loadcustomlogimpl(properties props) {
 // 從 mybatis 的 typealiasregistry 中查找 logimpl 鍵所對應值的類對象
 // 這里 logimpl 對應的 value 值可以從 org.apache.ibatis.session.configuration 的構造方法中找到
 // 注意 log 類,這是 mybatis 內(nèi)部對日志對象的抽象
 class<? extends log> logimpl = resolveclass(props.getproperty("logimpl"));
 // 將查找到的 class 對象設置到 configuration 對象中
 configuration.setlogimpl(logimpl);
}

很簡單的一個方法,每行都有注釋,其中 configuration.setlogimpl() 里面調(diào)用了 logfactory.usecustomlogging() ,這出現(xiàn)了新類 logfactory 類,接下來我們就來聊聊這個類。

logfactory

usecustomlogging()方法

logfactory 是框架內(nèi)部獲取 log 對象的手段,通過它的名字也能看出來。它有如下幾類方法:

?
1
2
3
4
5
6
7
8
// 注意這個類型的方法都是同步方法
public synchronized static usexxxlogging(...);
 
public static log getlog(...);
 
private static tryimplementation(runnable);
 
private static setimplementation(class);

剛剛我們看到被調(diào)用的方法 usecustomlogging() 方法,是用來設置內(nèi)部使用的日志框架, mybatis 自身已經(jīng)適配了一些常見的日志框架,如 slf4j 、 commons log 、 log4j 等等。

usecustomlogging() 方法內(nèi)部調(diào)用 setimplementation(class) 方法,此方法代碼如下,功能簡單:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
private static void setimplementation(class<? extends log> implclass) {
 try {
  // 獲取 log實現(xiàn)類的構造方法,它只有一個字符串作為參數(shù)
  constructor<? extends log> candidate = implclass.getconstructor(string.class);
 
  // 創(chuàng)建一個 log 對象,打印 debug 日志
  log log = candidate.newinstance(logfactory.class.getname());
  if (log.isdebugenabled()) {
   log.debug("logging initialized using '" + implclass + "' adapter.");
  }
 
  // ...
  // 把 candidate 對象設置到 logfactory 的靜態(tài)變量 logconstructor,這個靜態(tài)變量在 getlog() 方法
  // 中被用到
  logconstructor = candidate;
 } catch (throwable t) {
  throw new logexception("error setting log implementation. cause: " + t, t);
 }
}

log 接口

剛剛我們接觸到了 log 這個類,它是一個接口,是 mybatis 內(nèi)部使用的日志對象的抽象,它是為了兼容市面上各種各樣的日志框架,使用了適配器模式,通過 log 接口來連接 mybatis 和其他日志框架,通過實現(xiàn) log 接口連著 mybatis 和需要適配的日志框架。

log 接口代碼如下,先試著發(fā)現(xiàn)該接口與其他常見的日志接口的區(qū)別:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public interface log {
 
 boolean isdebugenabled();
 
 boolean istraceenabled();
 
 void error(string s, throwable e);
 
 void error(string s);
 
 void debug(string s);
 
 void trace(string s);
 
 void warn(string s);
 
}

可有發(fā)現(xiàn)?log 接口缺少了 info 級別的日志輸出方法,個人猜測應該是 mybatis 內(nèi)部不需要 info 級別的日志輸出,畢竟 log 接口設計之初就是為了內(nèi)部使用,而框架使用者是不會采用 mybatis 的日志作為系統(tǒng)的日志。注意一點: 實現(xiàn)了 log 接口的類必須擁有一個參數(shù)只有一個字符串的構造方法 ,mybatis 就是通過這個構造方法創(chuàng)建日志對象的。

mybatis 適配了許多常見的日志框架,這里就單單介紹 log4jimpl 類,它代碼非常簡單:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
public class log4jimpl implements log {
 
 private static final string fqcn = log4jimpl.class.getname();
 
 // 這里包裝了 log4j 框架的日志對象,從而實現(xiàn)適配
 private final logger log;
 
 public log4jimpl(string clazz) {
 log = logger.getlogger(clazz);
 }
 
 @override
 public boolean isdebugenabled() {
 return log.isdebugenabled();
 }
 
 @override
 public boolean istraceenabled() {
 return log.istraceenabled();
 }
 
 @override
 public void error(string s, throwable e) {
 log.log(fqcn, level.error, s, e);
 }
 
 @override
 public void error(string s) {
 log.log(fqcn, level.error, s, null);
 }
 
 @override
 public void debug(string s) {
 log.log(fqcn, level.debug, s, null);
 }
 
 @override
 public void trace(string s) {
 log.log(fqcn, level.trace, s, null);
 }
 
 @override
 public void warn(string s) {
 log.log(fqcn, level.warn, s, null);
 }
 
}

tryimplementation() 方法

logfactory 類再介紹一下被靜態(tài)代碼塊使用的方法 tryimplementation(runnable) 。靜態(tài)代碼塊代碼如下:

?
1
2
3
4
5
6
7
8
9
static {
 // 依次執(zhí)行如下代碼,當沒有該類會拋 classnotfoundexception ,然后繼續(xù)執(zhí)行
 tryimplementation(logfactory::useslf4jlogging);
 tryimplementation(logfactory::usecommonslogging);
 tryimplementation(logfactory::uselog4j2logging);
 tryimplementation(logfactory::uselog4jlogging);
 tryimplementation(logfactory::usejdklogging);
 tryimplementation(logfactory::usenologging);
}

這個方法有點迷惑性,因為它使用 runnable 接口作為參數(shù),而 usexxxlogging() 方法又是同步方法,很容易聯(lián)想到多線程,實際上這里并沒有, runnable 接口不結合 thread 類使用它就是一個普通的函數(shù)接口。除去這些就沒什么了,不過是調(diào)用了 runnable 的 run() 方法而已。

getlog() 方法

getlog() 沒什么多說的,就是通過反射創(chuàng)建 log 接口實現(xiàn)類,這里沒有使用到緩存,每次調(diào)用都是創(chuàng)建一個新的對象。

jdbc 包

這個包與其他包有些不同,它的職能是為各個階段的流程提供日志打印,該包一共就五個類,它們的關系如下:

MyBatis源碼分析之日志logging詳解

除了 basejdbclogger 類其他類都實現(xiàn)了 invocationhandler 接口,這個接口是 jdk 提供的動態(tài)代理接口,所以顯而易見可以知道它們就是通過代理在各個階段打印相應的日志。

以下為 basejdbclogger 類的部分說明:

  • set_methods:靜態(tài)字段,記錄 preparedstatement 中 set 開頭的的方法名
  • execute_methods:靜態(tài)字段,記錄 sql 執(zhí)行的方法名
  • columnxxx:實例字段,記錄 sql 參數(shù)信息
  • statementlog:日志對象
  • querystack:查詢棧數(shù)
  • getparametervaluestring():將 sql 參數(shù)轉(zhuǎn)為一個字符串
  • removebreakingwhitespace():移除 sql 中多余的空白字符
  • prefix():獲取前綴 ==>/<==

而其余四個類都是簡單的邏輯:判斷執(zhí)行的方法是否為指定方法,然后打印相應的日志。

總結

以上便是個人研究 logging 包的內(nèi)容,本包使用了以下設計模式(包含不限于):

  • 適配器模式
  • 代理模式

其中適配器模式應該是一個比較不錯的示例,可做參考。

好了,以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對服務器之家的支持。

原文鏈接:https://segmentfault.com/a/1190000018365826

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 伊人久久国产 | 国产精品亚洲第一区在线暖暖韩国 | 青青久久 | 亚洲视频欧洲视频 | 中文字幕亚洲欧美日韩在线不卡 | www.福利视频 | 亚洲日本va中文字幕 | 中文字幕高清视频 | 国产精品久久久久久亚洲调教 | 午夜精品久久久久久久白皮肤 | 久久综合九色综合网站 | 亚洲区在线 | 福利片一区二区 | 亚洲免费观看视频 | 黄色一级片免费 | 18.wxww.成人性视频高清 | 在线视频亚洲 | 欧美日韩在线电影 | 在线色网 | 欧美日本韩国一区二区三区 | 日韩精品免费在线观看 | 精品国产凹凸成av人导航 | 欧美精品久久一区 | 国产精品久久久久久久久久久久久久 | 久久久精品网站 | 欧美一级久久久 | 免费在线看污网站 | 国产大学生援交视频在线观看 | 中文字幕一区二区三区精彩视频 | 日韩欧美久久 | 亚洲精品第一 | 情一色一乱一欲一区二区 | 亚洲欧美日韩在线一区 | 中文字幕乱码亚洲无线三区 | 欧美国产一区二区三区 | 亚洲免费在线看 | 亚洲黄色在线视频 | av激情在线| 一区二区欧美视频 | 一区二区三区免费播放 | 日韩一区二区三区在线观看 |