日志记录问题引子:
在通常开发接口中,经常要记录日志。但是如果这些代码直接写在代码中,后期维护太难,而且也会造成过多的冗余代码。
现在可以使用spring的aop来实现这个功能:
疑问:
1、我们不是所有的接口都需要记录日志
2、需要对每个接口定义一个标识,以后查询日志方便
解决方案:
可以自定义个annotation来解决这两个问题,而aop切面是这个annotation。这样只要有这个自定义的annotation都会去记录日志了。
具体实现:
需要的jar(spring的各类jar就不说了)
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjrt</artifactId>
<version>1.8.9</version>
</dependency>
自定义annotation
package cn.zwz.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogCode {
String logCode() default "";
}
具体实现日志记录代码
package cn.zwz.aop;
import java.lang.reflect.Method;
import java.net.InetAddress;
import java.util.Date;
import java.util.UUID;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import cn.zwz.annotation.LogCode;
/**
* 保存日志
* @author zwz
* @Date 2016-12-19
*/
@Aspect
public class LogAspect {
@Autowired
private LogUtils logUtils;
@Around("@annotation(cn.zwz.annotation.LogCode)")
public Object aroundLog(ProceedingJoinPoint pjp) throws Throwable {
// 获取切入的 Method
MethodSignature joinPointObject = (MethodSignature) pjp.getSignature();
Method method = joinPointObject.getMethod();
LogCode annotation = method.getAnnotation(LogCode.class);
//获得日志标识
String logCode = annotation.logCode();
//执行实际方法
Object resBody = pjp.proceed();
//获得返回结果
String resStr=String.valueOf(resBody);
//异步保存请求日志
logUtils.addLog(Object);
return resStr;
}
}
1、日志记录采用异步保存,防止保存日志花费很多时间造成接口响应超时
2、logUtils采用接口形式,可以实现多方便保存接口方式,比如:直接保存到数据库,推送到mq,保存到nosql。