log4j中对Exception的记录

40 篇文章 0 订阅

这段时间折腾利用AOP来做简易的Exception处理框架的事。事因如下:

这是一个在Service层自定义的异常,用于将Service层的异常进行包装,再往高层抛出(如Action层)

public class BusinessException extends Exception{   
	    
	public BusinessException(String msg, Throwable ex){      
		super(msg, ex);
	}   
	    
	public BusinessException(String msg){   
		super(msg);   
	}   
	    
	public BusinessException(Throwable ex){   
		super(ex);  
	}   
}   

AOP相关代码如下:

/** 向Service层织入"异常捕获及抛出, 并记录日志 " */
	@Around(value = "serviceCall() && @annotation(buss)")
	public Object serviceInterceptor(ProceedingJoinPoint pj, BusinessLog buss)
			throws Throwable {
		Object object = null;
		try {
			object = pj.proceed();
		} catch (Exception e) {
			log.error("***Error: ", e);
			if (buss != null) {
				/** 抛出重新包装的Exception */
				throw new BusinessException(buss.exMsg(), e);
			} else
				throw e;

		}

		return object;
	}




原本是想在Service捕获到异常后,先进行日志记录,而后再将友有的异常信息抛出以方便高层捕获并显示相关信息到用户界面。

实际运行过程中,日志信息是正常记录了,但有个地方出现了点小问题。

throw new BusinessException(buss.exMsg(), e);

throw的异常抛出后会将包装过的异常信息额外的记录一次,同样也写入到了我的日志记录文件中。由于我们在之前已经用log.error()进行记录过了,所以

这些信息应该说是重复了,并不是我们真正想要的行为。大家都知道,StackTrace一般都是很长的一些字串,这无疑使日志文件的大小几乎是翻了一倍。

刚开始,一直不清楚,throw new BusinessException(...)这句实质上并没有做多少事的代码为什么会导致Log4j将日志信息记录到日志文件中。

我的Log4j设置的记录级别是ERROR,也就是只有错误信息级别为ERROR、FATAL或者OFF的信息才会被记录到日志文件中。经分析,可以明确地

知道此次记录到日志中的信息是ERROR级别的。所以,就会有这样一个疑问,为什么一句throw new BusinessException(...)的简单代码,而且并没有调用

log.error(),最后确会被当作错误信息记录到日志中呢?

之后我又把 它换成了了:throw new Exception(..., ...); 同样地,Exception的信息还是被记录到了日志。那这究竟是什么原因呢?


那就得从异常的基础说起了,java.lang.Exception是从java.lang.Throwable继承来的,它是很多异常的父类,包括RuntimeException和很多非RuntimeException。

    Exception类:运行异常,受检查异常

        运行异常:RuntimeException类及其子类

                 当程序中可能出现这类异常时,即使没有用try…catch语句捕获它,也没有用throws子句声明抛出它还是会编译通过。

        受检查异常:除了RuntimeException类及其子类外,其他的Exception类及其子类

                当程序中可能出现这类异常时,要么用try…catch捕获,要么用throws子句声明抛出,否则编译不会通过。


在本文的最开始,其实我已经用红色字体标明,BusinessException是继承自Exception的 ,所以它就有可能是运行异常或者受检查异常。

假如程序运行过程中,它是作为运行异常抛出的话,那自然没有什么问题。但如果它是受检查异常,虽然从上面的代码我们看到了有用throws Trhrowable声明

可能抛出异常,可这仅仅只是为了让它编译通过而已。如果真遇到受检查异常的话,那么它就不能像运行时异常那样可以不处理。换之,系统或者log4j则是把它

当成是ERROR对待,所以这也就是为什么当我调用throw new BusinessException(...)这句代码的时候,log4j会将包装过的异常信息记录到日志文件中去。

那么为了不让它被记录到日志文件中去,我们该怎么做?非常简单,既然RuntimeException是可以不做处理的,那我们只要让BusinessException继承自

RuntimeException,如下:

AOP相关代码如下:

public class BusinessException extends RuntimeException{   
	    
	public BusinessException(String msg, Throwable ex){      
		super(msg, ex);
	}   
	    
	public BusinessException(String msg){   
		super(msg);   
	}   
	    
	public BusinessException(Throwable ex){   
		super(ex);  
	}   
}   



折腾了这个,弄了好几个小时。最后想想,还是基础不够扎实。

仅在此记!

  By      M

 2012/03/06 13:47

原文出处:http://blog.csdn.net/oathevil/article/details/7324373

转载请保留!!!







  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值