学习使用Spring AOP写方法Debug日志

package org.allenz.tadths.debug;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

/**
* 日志注解,通过Spring AOP打印被注解的方法的参数、返回值和异常信息。<br>
*
* @author Allenz
* @version 1.0
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {
boolean before() default false;

boolean afterReturning() default false;

boolean afterThrowing() default true;
}


package org.allenz.tadths.debug;

import java.lang.reflect.Method;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.AnnotationUtils;

/**
* 日志注解实现。
*
* @author Allenz
* @version 1.0
*/
public class LogAdvice {

private Class<?> targetClass;
private Method targetMethod;
private Logger logger;
private boolean hasLogAnnotation;
private boolean before;
private boolean afterReturning;
private boolean afterThrowing;
private String beforeLog;

/**
* 在日志打印方法参数。
*
* @param jp
* 连接点
*/
public void before(JoinPoint jp) {
Logger logger = this.getLogger(jp);
if (!logger.isDebugEnabled()) {
return;
}
if (!this.hasLogAnnotation(jp)) {
return;
}
StringBuilder logBuilder = new StringBuilder();
String methodName = jp.getSignature().getName();
logBuilder.append("Invoke ").append(methodName).append("(");
Object[] args = jp.getArgs();
if (args.length > 0) {
for (int i = 0; i < args.length; i++) {
logBuilder.append(args[i]).append(",");
}
logBuilder.deleteCharAt(logBuilder.length() - 1);
}
logBuilder.append(")");
// "Invoke MethodName(ParamValue1,ParamValue1...)"
String log = logBuilder.toString();
this.beforeLog = log;
if (this.before) {
logger.debug(log);
}
}

/**
* 在日志打印方法返回值。
*
* @param jp
* 连接点
* @ret 返回值
*/
public void afterReturning(JoinPoint jp, Object ret) {
Logger logger = this.getLogger(jp);
if (!logger.isDebugEnabled()) {
return;
}
if (!this.hasLogAnnotation(jp)) {
return;
}
StringBuilder logBuilder = new StringBuilder();
logBuilder.append("Return ").append(ret);
// "Return ReturnValue"
String log = logBuilder.toString();
// 打印方法参数
if (!this.before) {
logger.debug(this.beforeLog);
}
if (this.afterReturning) {
logger.debug(log);
}
}

/**
* 在日志打印方法异常。
*
* @param jp
* 连接点
* @param e
* 异常
*/
public void afterThrowing(JoinPoint jp, Throwable e) {
Logger logger = this.getLogger(jp);
if (!this.hasLogAnnotation(jp)) {
return;
}
if (!this.afterThrowing) {
return;
}
StringBuilder logBuilder = new StringBuilder();
logBuilder.append("Throws ").append(e.getClass().getName()).append("(")
.append(e.getLocalizedMessage()).append(")");
// "Throws ExceptionClassName(ExceptionMessage)"
String log = logBuilder.toString();
// 打印方法参数
if (!this.before) {
logger.error(this.beforeLog);
}
logger.error(log);
}

/**
* 获取被增强的对象的类型。
*
* @param jp
* 连接点
* @return 对象的类型
*/
private Class<?> getTargetClass(JoinPoint jp) {
if (this.targetClass == null) {
this.targetClass = jp.getTarget().getClass();
}
return this.targetClass;
}

/**
* 获取被增强的方法。
*
* @param jp
* 连接点
* @return 方法
*/
private Method getTargetMethod(JoinPoint jp) {
if (this.targetMethod == null) {
MethodSignature methodSignature = (MethodSignature) jp
.getSignature();
this.targetMethod = methodSignature.getMethod();
}
return this.targetMethod;
}

/**
* 从Logger工厂获取被增强对象的Logger。
*
* @param jp
* 连接点
* @return Logger
*/
private Logger getLogger(JoinPoint jp) {
if (this.logger == null) {
this.logger = LoggerFactory.getLogger(this.getTargetClass(jp));
}
return this.logger;
}

/**
* 检查被增强的方法是否拥有日志注解。
*
* @param jp
* 连接点
* @return 拥有返回真,没有返回假
*/
private boolean hasLogAnnotation(JoinPoint jp) {
if (!this.hasLogAnnotation) {
// 优先使用方法注解
Log logAnno = AnnotationUtils.findAnnotation(this.getTargetMethod(jp),
Log.class);
// 找不到方法注解,使用类注解
if (logAnno == null) {
logAnno = AnnotationUtils.findAnnotation(this.getTargetClass(jp),
Log.class);
}
if (logAnno != null) {
this.hasLogAnnotation = true;
this.before = logAnno.before();
this.afterReturning = logAnno.afterReturning();
this.afterThrowing = logAnno.afterThrowing();
}
}
return this.hasLogAnnotation;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值