springboot aop记录日志
一,添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
二,编写切面类
/** * @program: beidou * @description: 记录必要请求日志 * @author: shengkai * @create: 2018-08-23 15:31 **/ @Aspect @Component @Order(-5) public class WebLogAspect { private final Logger log = LoggerFactory.getLogger(WebLogAspect.class); private static ThreadLocal<Long> time = new ThreadLocal<Long>(){ protected Long initialValue() { long beginTime = System.currentTimeMillis(); return beginTime; } };//直接注入会有空指针问题 private static final ThreadLocal<InvokeLog> invokelog = new ThreadLocal<InvokeLog>(){ protected InvokeLog initialValue() { return new InvokeLog(); } }; @Autowired InvokeLogMapper invokeLogMapper; public WebLogAspect() { } /** * 定义一个切入点. * 解释下: * ~ 第一个 * 代表任意修饰符及任意返回值. * ~ 第二个 * 任意包名 * ~ 第三个 * 代表任意方法. * ~ 第四个 * 定义在web包或者子包 * ~ 第五个 * 任意方法 * ~ .. 匹配任意数量的参数. */ @Pointcut("@annotation(com.kuainiu.beidou.service.base.components.InvokeLog)") public void invokeLog(){ invokelog.set(new InvokeLog()); } @Before(value = "invokeLog()") public void doBefore(JoinPoint joinPoint) throws Throwable { time.set(System.currentTimeMillis()); // 接收到请求,记录请求内容 ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes(); HttpServletRequest request = attributes.getRequest(); // 记录下请求内容 log.info("URL : " + request.getRequestURL().toString()); log.info("HTTP_METHOD : " + request.getMethod()); log.info("IP : " + request.getRemoteAddr()); log.info("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName()); log.info("ARGS : " + Arrays.toString(joinPoint.getArgs())); InvokeLog invokeLog = invokelog.get(); invokeLog.setCreateTime(new Date()); invokeLog.setUrl(request.getRequestURL().toString()); invokeLog.setHttpMethod(request.getMethod()); invokeLog.setIp(request.getRemoteAddr()); invokeLog.setClassMethod(joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName()); invokeLog.setArgs(Arrays.toString(joinPoint.getArgs())); } @AfterReturning(returning = "ret", pointcut = "invokeLog()") public void doAfterReturning(Object ret) throws Throwable { // 处理完请求,返回内容 log.info("RESPONSE : " + ret); InvokeLog invokeLog = invokelog.get(); invokeLog.setResponse(ret.toString()); invokeLog.setTime((System.currentTimeMillis()-time.get())); invokeLogMapper.insert(invokeLog); } @After(value = "invokeLog()") public void after(){ } }
/** * @program: beidou * @description: 注解文件 * @author: shengkai * @create: 2018-08-24 08:59 **/ @Target({ElementType.METHOD,ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface InvokeLog { String name() default ""; String description() default ""; boolean printReturn() default true; }
注意:遇到aop一直不生效的问题,是因为切面类没有被spring启动类管理,解决:扫面切面类所在包
三,在需要记录日志的controller接口上加入自定义注解即可