异常日志处理-ThrowsAdvice

Posted 四季常青

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了异常日志处理-ThrowsAdvice相关的知识,希望对你有一定的参考价值。

  有的时候,为了保全代码的简洁,我们不希望在程序中看到一些跟程序逻辑的代码,譬如异常日志打印,这个时候就需要我们对程序中的异常日志进行统一的管理。spring aop 可以在不破坏程序逻辑的情况下很好的完成我们上面的需求。本文对对日志的处理使用到了ThrowsAdvice接口和spring aop

 

ThrowsAdvice接口

 1 /*
 2  * Copyright 2002-2008 the original author or authors.
 3  *
 4  * Licensed under the Apache License, Version 2.0 (the "License");
 5  * you may not use this file except in compliance with the License.
 6  * You may obtain a copy of the License at
 7  *
 8  *      http://www.apache.org/licenses/LICENSE-2.0
 9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package org.springframework.aop;
18 
19 /**
20  * Tag interface for throws advice.
21  *
22  * <p>There are not any methods on this interface, as methods are invoked by
23  * reflection. Implementing classes must implement methods of the form:
24  *
25  * <pre class="code">void afterThrowing([Method, args, target], ThrowableSubclass);</pre>
26  *
27  * <p>Some examples of valid methods would be:
28  *
29  * <pre class="code">public void afterThrowing(Exception ex)</pre>
30  * <pre class="code">public void afterThrowing(RemoteException)</pre>
31  * <pre class="code">public void afterThrowing(Method method, Object[] args, Object target, Exception ex)</pre>
32  * <pre class="code">public void afterThrowing(Method method, Object[] args, Object target, ServletException ex)</pre>
33  *
34  * The first three arguments are optional, and only useful if we want further
35  * information about the joinpoint, as in AspectJ <b>after-throwing</b> advice.
36  *
37  * <p><b>Note:</b> If a throws-advice method throws an exception itself, it will
38  * override the original exception (i.e. change the exception thrown to the user).
39  * The overriding exception will typically be a RuntimeException; this is compatible
40  * with any method signature. However, if a throws-advice method throws a checked
41  * exception, it will have to match the declared exceptions of the target method
42  * and is hence to some degree coupled to specific target method signatures.
43  * <b>Do not throw an undeclared checked exception that is incompatible with
44  * the target method‘s signature!</b>
45  *
46  * @author Rod Johnson
47  * @author Juergen Hoeller
48  * @see AfterReturningAdvice
49  * @see MethodBeforeAdvice
50  */
51 public interface ThrowsAdvice extends AfterAdvice {
52 
53 }

看接口说明可知,该接口上没有任何方法,但是实现了这个接口的类必须至少实现以下4个方法中的一个,否则程序报:

Caused by: java.lang.IllegalArgumentException: At least one handler method must be found in class

接口中的异常类可以为自己自定义的异常类,方法是通过反射调用。

1 public void afterThrowing(Exception ex)
2 public void afterThrowing(RemoteException)
3 public void afterThrowing(Method method, Object[] args, Object target, Exception ex)
4 public void afterThrowing(Method method, Object[] args, Object target, ServletException ex)

 

自定义异常类

技术分享
 1 package com.apt.study.exception;
 2 
 3 public class StudyException extends RuntimeException {
 4 
 5     /**
 6      * 
 7      */
 8     private static final long serialVersionUID = -6183216129830888521L;
 9 
10     /**
11      * 异常信息
12      */
13     protected String message;
14     
15     /**
16      * 异常编码
17      */
18     protected int code;
19     
20     public static final StudyException PARAM_VALIDATE_EXCEPTION = new StudyException(1234,"参数校验出错");
21     
22     public StudyException(int code, String msgFormat, Object... args) {
23         super(String.format(msgFormat, args));
24         this.code = code;
25         this.message = String.format(msgFormat, args);
26     }
27     
28     public StudyException(String message, Throwable cause) {
29         super(message, cause);
30     }
31 
32     public StudyException(Throwable cause) {
33         super(cause);
34     }
35 
36     public StudyException(String message) {
37         super(message);
38     }
39 
40     public String getMessage() {
41         return message;
42     }
43 
44     public void setMessage(String message) {
45         this.message = message;
46     }
47 
48     public int getCode() {
49         return code;
50     }
51 
52     public void setCode(int code) {
53         this.code = code;
54     }
55     
56     
57 }
View Code

 

异常日志处理类

 1 package com.apt.study.exception;
 2 
 3 import java.lang.reflect.Method;
 4 
 5 import org.slf4j.Logger;
 6 import org.slf4j.LoggerFactory;
 7 import org.springframework.aop.ThrowsAdvice;
 8 
 9 public class ExceptionLogHandler implements ThrowsAdvice{
10 
11     public Logger logger = LoggerFactory.getLogger(ExceptionLogHandler.class);
12     
13     public void afterThrowing(Method method, Object[] args, Object target, StudyException ex) {
14         logger.error("ExceptionLogHandler--StudyExcception");
15         logger.info("-------errCode:" + ex.getCode() + "; errMessage:" + ex.getMessage());
16         errorClassInfo(ex);
17         logger.info("-------" + ex.fillInStackTrace());
18     }
19     
20     public void afterThrowing(Method method, Object[] args, Object target, Exception ex) {
21         
22         logger.error("ExceptionLogHandler--Exception");
23         logger.error("------->Erro Class: "+ target.getClass().getName());
24         logger.error("------->Error method:"+ method.getName());
25         
26         if(args != null) {
27             for(int i=0; i<args.length; i++) {
28                 logger.error("------->args[" + i + "]: " + args[i]);
29             }
30         }
31         
32         logger.error("------->Exception class: " + ex.getClass().getName());
33         errorClassInfo(ex);
34         logger.error("------->" + ex.fillInStackTrace());
35     }
36     
37     //打印抛出异常地方的信息
38     private void errorClassInfo(Exception ex) {
39         /*
40          * ex.getStackTrace()返回堆栈跟踪元素的数组,每个元素表示一个堆栈帧。数组的第零个元素(假定数据的长度为非零)表示堆栈顶部,
41          * 它是序列中最后的方法调用。
42          * 通常,这是创建和抛出该 throwable 的地方。数组的最后元素(假定数据的长度为非零)表示堆栈底部,它是序列中第一个方法调用
43          */
44         StackTraceElement[] stackTraceElementArr= ex.getStackTrace();
45         StackTraceElement stackTraceElement = stackTraceElementArr[0];
46         logger.error("------->Erro File:" + stackTraceElement.getFileName());
47         logger.error("------->Erro Method:" + stackTraceElement.getMethodName());
48         logger.error("------->Erro Line:" + stackTraceElement.getLineNumber());
49     }
50     
51 }

 

spring-context.xml 配置

<!-- 异常信息 拦截 -->
     <bean id="exceptionLog" class="com.apt.study.exception.ExceptionLogHandler"></bean>  
     <aop:config>
        <aop:pointcut id="exceptionTrade" expression="execution(* com.apt.study.service.*.*(..))" />
        <aop:advisor pointcut-ref="exceptionTrade" advice-ref="exceptionLog"/>
    </aop:config>

 

以上是关于异常日志处理-ThrowsAdvice的主要内容,如果未能解决你的问题,请参考以下文章

SpringAOP使用扩展

异常和TCP通讯

spring学习 十 schema-based 异常通知,和环绕通知

常用python日期日志获取内容循环的代码片段

片段中的空指针异常

python 面向对象约束 异常处理 MD5 日志处理