码迷,mamicode.com
首页 > 其他好文 > 详细

避免每个类中都初始化日志类

时间:2016-06-22 17:20:39      阅读:640      评论:0      收藏:0      [点我收藏+]

标签:日志、log4j


写代码的时候,很多类里需要打日志,一般写法都是:

Logger log =  LoggerFactory.getLogger(XXX.class); // 或者参数给的是类名字符串


每个类里面都要写,好烦,能否封装一下,自动获取使用日志的类名,这样就不用每个类里都写了:


一个百试不爽的实现方式(通过异常栈获取):

public static Logger getLogger() {

	Logger logger = Logger.getLogger(getInvokingClassName());
	PropertyConfigurator.configure(getConfigFileName());

	return logger;
}
public static String getInvokingClassName()
{
	return new Throwable().getStackTrace()[2].getClassName();
}

有人说这样的方式性能会有问题,网上有人给出了如下几种方式取得类名:

 // 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中都只能显示其自身所在的类信息,却得不到正在写日志的
    类的信息。


 其实,文首给出的实现也是jdk里的实现方式:

后面给出的代码是JDK1.4的源代码,和Log4J的源代码。说明其实现原理。
获得调用类,和方法名,就是需要获得当前运行栈的结构。
new Throwable().getStackTrace() 会返回当前运行栈的结构层次。
利用这种原理,可以获得整个运行栈的调用关系。

JDK1.4的java.util.logging包, 通过Throwable.getStackTrace()方法实现的。
// Get the stack trace.
StackTraceElement stack[] = (new Throwable()).getStackTrace(); 


log4j的实现也是异曲同工:

org.apache.log4j.spi.LocationInfo类。
先用Throwable.printStackTrace()方法把Exception信息打印到一个字符串里。
然后按行分析这个字符串。抽出调用类和方法。


JDK1.5在Thread类里面引入了getStackTrace()和getAllStackTraces()两个方法。这下子,我们不用 (new Throwable()).getStackTrace ();可以调用

Thread.getCurrentThread().getStackTrace()来获得当前线程的运行栈信息。不仅如此,只要权限允许,还可以获得其它线程的运行栈信息。不幸的是,虽然可以拿到栈信息,但是日志打印的时候依然显示的是Thread.getCurrentThread().getStackTrace()该语句所在的类的信息。



避免每个类中都初始化日志类

标签:日志、log4j

原文地址:http://langlichong.blog.51cto.com/8846944/1791773

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!