避免每个类中都初始化日志类
寫代碼的時候,很多類里需要打日志,一般寫法都是:
Logger log = ?LoggerFactory.getLogger(XXX.class); // 或者參數(shù)給的是類名字符串
每個類里面都要寫,好煩,能否封裝一下,自動獲取使用日志的類名,這樣就不用每個類里都寫了:
一個百試不爽的實現(xiàn)方式(通過異常棧獲取):
public?static?Logger?getLogger()?{Logger?logger?=?Logger.getLogger(getInvokingClassName());PropertyConfigurator.configure(getConfigFileName());return?logger; } public?static?String?getInvokingClassName() {return?new?Throwable().getStackTrace()[2].getClassName(); }有人說這樣的方式性能會有問題,網(wǎng)上有人給出了如下幾種方式取得類名:
?//?1、通過SecurityManager的保護方法getClassContext()??String?clazzName?=?new?SecurityManager()?{??public?String?getClassName()?{??return?getClassContext()[1].getName();??}??}.getClassName();??System.out.println(clazzName);?****以上這個總覺得哪里有限制*****2、通過分析匿名類名稱()??String?clazzName3?=?new?Object()?{??public?String?getClassName()?{??String?clazzName?=?this.getClass().getName();??return?clazzName.substring(0,?clazzName.lastIndexOf('$'));??}??}.getClassName();??System.out.println(clazzName3);3、通過Thread的方法getStackTrace()??String?clazzName4?=?Thread.currentThread().getStackTrace()[2].getClassName();??System.out.println(clazzName4);注意:雖然以上3中方式都可以拿到類名,但是,寫日志的時候,我們是要從日志里看出日志是出自那個類,而以上3中都只能顯示其自身所在的類信息,卻得不到正在寫日志的類的信息。?其實,文首給出的實現(xiàn)也是jdk里的實現(xiàn)方式:
后面給出的代碼是JDK1.4的源代碼,和Log4J的源代碼。說明其實現(xiàn)原理。
獲得調(diào)用類,和方法名,就是需要獲得當(dāng)前運行棧的結(jié)構(gòu)。
new Throwable().getStackTrace() 會返回當(dāng)前運行棧的結(jié)構(gòu)層次。
利用這種原理,可以獲得整個運行棧的調(diào)用關(guān)系。
JDK1.4的java.util.logging包, 通過Throwable.getStackTrace()方法實現(xiàn)的。
// Get the stack trace.
StackTraceElement stack[] = (new Throwable()).getStackTrace();?
log4j的實現(xiàn)也是異曲同工:
org.apache.log4j.spi.LocationInfo類。
先用Throwable.printStackTrace()方法把Exception信息打印到一個字符串里。
然后按行分析這個字符串。抽出調(diào)用類和方法。
JDK1.5在Thread類里面引入了getStackTrace()和getAllStackTraces()兩個方法。這下子,我們不用 (new Throwable()).getStackTrace ();可以調(diào)用
Thread.getCurrentThread().getStackTrace()來獲得當(dāng)前線程的運行棧信息。不僅如此,只要權(quán)限允許,還可以獲得其它線程的運行棧信息。不幸的是,雖然可以拿到棧信息,但是日志打印的時候依然顯示的是Thread.getCurrentThread().getStackTrace()該語句所在的類的信息。
轉(zhuǎn)載于:https://blog.51cto.com/langlichong/1791773
總結(jié)
以上是生活随笔為你收集整理的避免每个类中都初始化日志类的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 史上最全最强SpringMVC详细示例实
- 下一篇: 精益 React 学习指南 (Lean