1. 自定义注解
import java.lang.annotation.*;
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface SysLog {
String value() default "";
}
注解与作用:
2. Controller添加自定义注解
@PostMapping("/login")
@ResponseBody
@SysLog(value = "用户登录")
public R login(String username, String password) {
/*
* 登陆校验逻辑
* */
return R.ok();
}
3. 切面
@Aspect
@Component
public class SysLogAspect {
/**
* 定义切点 @Pointcut
* 在注解的位置切入代码
*/
@Pointcut("@annotation( com.*.*.*.*.SysLog)")
public void logPoinCut() {}
/**
* 切面 配置通知
*/
@AfterReturning(value ="logPoinCut()",returning = "r")
public void sysLog(JoinPoint joinPoint,Object r) {
long startTime = System.currentTimeMillis();
// 织入点处的方法返回数据
R result = (R)r;
//获取织入点处的方法
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
//获取操作
Log myLog = method.getAnnotation(Log.class);
if (Objects.nonNull(myLog)) {
String value = myLog.value();
}
//获取请求的类名
String className = joinPoint.getTarget().getClass().getName();
//获取请求的方法名
String methodName = method.getName();
//请求的参数
Object[] args = joinPoint.getArgs();
//将参数所在的数组转换成json
String params = JSON.toJSONString((args), SerializerFeature.IgnoreNonFieldGetter);
//获取用户ip地址
HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
String ipAddr = IPUtils.getIpAddr(request);
//获取耗时
long endTime = System.currentTimeMillis();
long time = endTime - startTime;
}
}
AOP的五种通知类型:
@Before
前置通知:在切入点方法执行之前执行
@After
后置通知:在切入点方法执行之后执行,无论切入点方法内部是否出现异常,后置通知都会执行。
@Around
环绕通知:手动调用切入点方法并对其进行增强的通知方式。
@AfterReturning
返回后通知:在切入点方法执行之后执行,如果切入点方法内部出现异常将不会执行。
@AfterThrowing
抛出异常后通知:在切入点方法执行之后执行,只有当切入点方法内部出现异常之后才执行。