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;
}
}