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;
}
}
分享到:
相关推荐
一、适合人群 1、具备一定Java编程基础,初级开发者 2、对springboot,mybatis,mysql有基本认识 3、对spring aop认识模糊的,不清楚如何实现Java 自定义注解的 ...4、spring boot,mybatis,druid,spring aop的使用
可扩展性强:使用 Spring AOP 进行方法耗时监测,可以方便的对其他的切面进行扩展,例如:日志、异常处理、权限控制等切面。 4. 提高系统性能:通过对系统中的方法进行耗时监测,可以及时发现系统中的性能瓶颈,...
Spring AOP 日志管理 实例LoggingThrowsAdvice.java
本资源用来展示如何使用 spring aop 进行日志记录,例子里面通过aop的配置,把产生的日志存放到当前项目的根目录下,而且对方法执行过程中的参数进行了记录,对于aop如何记录日志不清楚的同学可以看看。
spring AOP 切面日志 分层打日志
spring aop做的日志管理,网上看的,没测试过。
spring aop切面拦截指定类和方法实现流程日志跟踪 一般情况下,在不侵入业务代码的情况下,需要做流程日志跟踪是比较合理的 采用springaop切面思想
springaop多数据库读写分离
spring aop spring aop spring aop spring aop spring aop spring aop spring aop spring aop spring aop
spring aop jar 包
spring-aop-1.1.1.jar spring-aop-1.2.6.jar spring-aop-1.2.9.jar spring-aop-2.0.2.jar spring-aop-2.0.6.jar spring-aop-2.0.7.jar spring-aop-2.0.8.jar spring-aop-2.0.jar spring-aop-2.5.1.jar spring-aop-...
此工程为使用eclipse创建java project,使用jdk1.8,项目中包含完整的代码和jar包,导入eclipse即可运行
使用SpringAop使用Oracle数据权限控制
采用SpringAOP拦截Controller,Service实现操作日志管理,统一处理异常,登陆日志管理,是SpringAOP的应用实践。通过SpringAOP的处理,可以方便移植日志管理功能,是个不错的学习demo
描述一下Spring AOP? 在Spring AOP中关注点(concern)和横切关注点(cross-cutting concern)有什么不同? AOP有哪些可用的实现? Spring中有哪些不同的通知类型(advice types)? Spring AOP 代理是什么? 引介...
通过对SRPING aop的使用和研究,总结出来的SPRING AOP使用原理,以及在使用spring aop过程中要注意的问题
springaop拦截controller日志
NULL 博文链接:https://conkeyn.iteye.com/blog/2354644
Spring Aop的使用实例
基于注解实现SpringAop基于注解实现SpringAop基于注解实现SpringAop