三要素: 1切点(从哪里切) 2切面(切入什么) 3切入时间(前置,后置,环绕)
1切点--自定义注解,相当于在类中打个标识让切面认识
/**
* 自定义一个注解(让切面知道往哪里切)
* @author czh
*/
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyAnnotation {
}
2切面--你要切入的内容
/**
* @author czh
*/
@Aspect
@Component
@Slf4j
public class MyAdvice {
//MyAnnotation 类所在的包名
@Pointcut("@annotation(com.demoutil.mylearn.aop.MyAnnotation )")
private void MyCheck() {
}
@Around("MyCheck()")
public Object MyCheck(ProceedingJoinPoint joinPoint) throws Throwable {
/**获取签名 */
Signature signature = joinPoint.getSignature();
/**通过signature签名获取方法信息 */
/* 获取包名 */
String packgeName = signature.getDeclaringTypeName();
/* 获取方法名 */
String funName = signature.getName();
log.info("即将执行的方法位于" + packgeName + "方法名为" + funName);
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
/* 获取被请求的url地址 */
String url = request.getRequestURL().toString();
/* 获取请求ip */
String ip = request.getRemoteAddr();
log.info("用户请求的url为:{},ip地址为:{}", url, ip);
/**拿到一个参数数据数组 */
Object[] objects = joinPoint.getArgs();
/**拿到json中的key为id的值 */
Long id = ((JSONObject) objects[0]).getLong("id");
/**拿到json中的key为name的值 */
String name = ((JSONObject) objects[0]).getString("name");
log.info("id为" + id);
log.info("name为" + name);
/** 如果参数不通过,不放行 */
if (id < 0) {
return JSON.parseObject("{\"message\":\"illegal id\",\"code\":403}");
}
/**放行,跳到正常的执行接口 */
return joinPoint.proceed();
}
}
3切入时间--前置通知,后置通知,环绕通知等,具体看具体需求
@Around("MyCheck()") ---------->@Before @After
将上述代码中的注解修改为前置,后置或环绕
4测试调用
@RestController
@Slf4j
public class AopController {
@GetMapping(value = "/check")
@PermissionAnnotation()
public JSONObject getGroupList(@RequestBody JSONObject request) {
String s1 = request.get("id").toString();
log.info(s1);
return JSON.parseObject("{\"message\":\"SUCCESS\",\"code\":200}");
}
}