`

学习使用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;
	}

}
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics