山西住房和建设厅网站国内免费建网站
一、前言
在上篇文章中,我们使用了AOP思想实现日志记录的功能,代码中采用了指定连接点方式(@Pointcut(“execution(* com.nowcoder.community.controller..(…))”)),指定后不需要在进行任何操作就可以记录日志了,但是如果我们对某些controller不想记录日志,就需要更改指定的切点,灵活性较差。因此采用注解+AOP方式,实现更灵活的日志记录功能。
二、注解实现代码
package com.nowcoder.community.annotation;import java.lang.annotation.*;/*** @author Janson* @Description AOP日志记录注解* @Date 2023/5/12* @Target LogAspect 注解的作用目标* @Retention 指定注解的保留时间*/@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LogAspect {/*** title 自定义名称* description 自定义描述* @return*/String title() default "";String description() default "";
}
三、AOP日志记录类实现代码
定义切点(织入点)
execution(* com.nowcoder.community.controller..(…))
- 第一个 * 表示 支持任意类型返回值的方法
- com.nowcoder.community.controller 表示这个包下的类
- 第二个 * 表示 controller包下的任意类
- 第三个 * 表示 类中的任意方法
- (…) 表示方法可以拥有任意参数
可以根据自己的需求替换。
package com.nowcoder.community.aspect;import com.nowcoder.community.annotation.LogAspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;/*** @author Janson* @Description AOP日志记录,此方案不统一设置连接点 @Pointcut,而是采用注解方式,指定连接的方法* @Date 2023/5/12*/
@Aspect
@Component
public class LogAspectAnnotationTest {/*** 定义切点(织入点)* execution(* com.nowcoder.community.controller.*.*(..))* - 第一个 * 表示 支持任意类型返回值的方法* - com.nowcoder.community.controller 表示这个包下的类* - 第二个 * 表示 controller包下的任意类* - 第三个 * 表示 类中的任意方法* - (..) 表示方法可以拥有任意参数* 可以根据自己的需求替换。**/@Before(value = "@annotation(controllerLog)")public void before(JoinPoint joinPoint, LogAspect controllerLog){String className = joinPoint.getClass().getName();String methodName = joinPoint.getSignature().getName();ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();if (attributes == null){return;}String ip = attributes.getRequest().getRemoteHost();String requestURI = attributes.getRequest().getRequestURI();String requestMethod = attributes.getRequest().getMethod();String title = controllerLog.title();String description = controllerLog.description();System.out.println("title is " + title + ",description is " + description);System.out.println("before excute ······");System.out.println(String.format("用户: [%s] 的请求路径为:[%s], 请求方式为: [%s],请求类名为: [%s], 请求方法名为: [%s]", ip,requestURI,requestMethod,className,methodName));}@After(value = "@annotation(controllerLog)")public void after(JoinPoint joinPoint, LogAspect controllerLog){String className = joinPoint.getClass().getName();String methodName = joinPoint.getSignature().getName();ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();if (attributes == null){return;}String ip = attributes.getRequest().getRemoteHost();String requestURI = attributes.getRequest().getRequestURI();String requestMethod = attributes.getRequest().getMethod();String title = controllerLog.title();String description = controllerLog.description();System.out.println("title is " + title + ",description is " + description);System.out.println("after excute ······");System.out.println(String.format("用户: [%s] 的请求路径为:[%s], 请求方式为: [%s],请求类名为: [%s], 请求方法名为: [%s]", ip,requestURI,requestMethod,className,methodName));}@AfterReturning(value = "@annotation(controllerLog)")public void afterReturning(JoinPoint joinPoint, LogAspect controllerLog){String className = joinPoint.getClass().getName();String methodName = joinPoint.getSignature().getName();ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();if (attributes == null){return;}String ip = attributes.getRequest().getRemoteHost();String requestURI = attributes.getRequest().getRequestURI();String requestMethod = attributes.getRequest().getMethod();String title = controllerLog.title();String description = controllerLog.description();System.out.println("title is " + title + ",description is " + description);System.out.println("afterReturning excute ······");System.out.println(String.format("用户: [%s] 的请求路径为:[%s], 请求方式为: [%s],请求类名为: [%s], 请求方法名为: [%s]", ip,requestURI,requestMethod,className,methodName));}@AfterThrowing(value = "@annotation(controllerLog)",throwing = "e")public void afterThrowing(JoinPoint joinPoint, LogAspect controllerLog,Exception e){String className = joinPoint.getClass().getName();String methodName = joinPoint.getSignature().getName();ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();if (attributes == null){return;}String ip = attributes.getRequest().getRemoteHost();String requestURI = attributes.getRequest().getRequestURI();String requestMethod = attributes.getRequest().getMethod();String title = controllerLog.title();String description = controllerLog.description();System.out.println("title is " + title + ",description is " + description);System.out.println("afterThrowing excute ······" + e.getMessage());System.out.println(String.format("用户: [%s] 的请求路径为:[%s], 请求方式为: [%s],请求类名为: [%s], 请求方法名为: [%s],请求失败原因: [%s]", ip,requestURI, requestMethod,className,methodName,e.getMessage()));}@Around(value = "@annotation(controllerLog)")public void around(ProceedingJoinPoint joinPoint, LogAspect controllerLog) throws Throwable {String className = joinPoint.getTarget().getClass().getName();String methodName = joinPoint.getSignature().getName();System.out.println("className is : " + className + ". methodName is : " + methodName);ServletRequestAttributes attributes = (ServletRequestAttributes)RequestContextHolder.getRequestAttributes();if (attributes == null){return;}// 请求ipString ip = attributes.getRequest().getRemoteHost();// 请求路径String requestURI = attributes.getRequest().getRequestURI();// 请求方法String requestMethod = attributes.getRequest().getMethod();String title = controllerLog.title();String description = controllerLog.description();System.out.println(String.format("用户: [%s] 的请求路径为:[%s], 请求方式为: [%s],请求类名为: [%s], 请求方法名为: [%s]", ip,requestURI,requestMethod,className,methodName));Object obj = null;try {obj = joinPoint.proceed();} catch (Throwable e) {System.out.println("我捕获了异常");throw new RuntimeException("执行失败",e);}System.out.println(String.format("用户: [%s] 的请求路径为:[%s], 请求方式为: [%s],请求类名为: [%s], 请求方法名为: [%s]", ip,requestURI,requestMethod,className,methodName));System.out.println("around excute after ········");}
}