自定义注解使用Spring AOP

自定义注解
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
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值