自定义注解
package com.myelephant.projects.aop;
import java.lang.annotation.*;
/**
* @Author: StephenZhang
* @date: 2021-04-14 11:26
*/
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LoginMsg {
String[] key();
}
Aspect
package com.myelephant.projects.aop;
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.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Arrays;
/**
* @Author: StephenZhang
* @date: 2021-04-14 11:33
*/
@Aspect
@Component
public class AspectLoginMsg {
@Around("@annotation(loginMsg)")
public synchronized Object userLoginMsg(ProceedingJoinPoint joinPoint, LoginMsg loginMsg) throws Throwable {
System.out.println(Arrays.toString(loginMsg.key()));
//1.获取用户行为日志(ip,username,operation,method,params,time,createdTime)
//获取类的字节码对象,通过字节码对象获取方法信息
Class<?> targetCls = joinPoint.getTarget().getClass();
//获取方法签名(通过此签名获取目标方法信息)
MethodSignature ms = (MethodSignature) joinPoint.getSignature();
//获取目标方法上的注解指定的操作名称
Method targetMethod = targetCls.getDeclaredMethod(
ms.getName(),
ms.getParameterTypes());
System.out.println("targetMethod=" + targetMethod);
//获取目标方法名(目标类型+方法名)
String targetClsName = targetCls.getName();
String targetObjectMethodName = targetClsName + "." + ms.getName();
System.out.println(targetObjectMethodName);
//获取请求参数
String targetMethodParams = Arrays.toString(joinPoint.getArgs());
System.out.println(targetMethodParams);
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
assert attributes != null;
HttpServletRequest request = attributes.getRequest();
System.out.println(request.getRequestURL());
System.out.println(request.getMethod());
return joinPoint.proceed();
}
}
注解参数说明
execution:用于匹配方法执行的连接点;
within:用于匹配指定类型内的方法执行;
this:用于匹配当前AOP代理对象类型的执行方法;注意是AOP代理对象的类型匹配,这样就可能包括引入接口也类型匹配;
target:用于匹配当前目标对象类型的执行方法;注意是目标对象的类型匹配,这样就不包括引入接口也类型匹配;
args:用于匹配当前执行的方法传入的参数为指定类型的执行方法;
@within:用于匹配所以持有指定注解类型内的方法;
@target:用于匹配当前目标对象类型的执行方法,其中目标对象持有指定的注解;
@args:用于匹配当前执行的方法传入的参数持有指定注解的执行;
@annotation:用于匹配当前执行方法持有指定注解的方法;
Controller
package com.myelephant.projects.aop;
import com.dandandog.framework.rest.controller.ApiController;
import com.dandandog.framework.rest.model.ApiResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiResponse;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* @Author: StephenZhang
* @date: 2021-04-14 11:25
*/
@RestController
@RequestMapping("/test")
@Api(value = "test aop", tags = {"测试AOP"})
public class AopController extends ApiController {
@GetMapping("/login")
@ApiOperation(value = "测试调试aop")
@ApiResponse(code = 200, message = "操作成功", response = String.class)
@LoginMsg(key = "coding")
public ApiResult<String> loginMsg(@RequestParam String msg) {
return success(msg);
}
}
使用Swagger调试
控制台打印
[coding]
targetMethod=public com.dandandog.framework.rest.model.ApiResult com.myelephant.projects.aop.AopController.loginMsg(java.lang.String)
com.myelephant.projects.aop.AopController.loginMsg
[admin]
http://xiaoxiangdz.test.utools.club/api/test/login
GET