SpringAOP 关键API详解

简介: 在Spring AOP中,JoinPoint和ProceedingJoinPoint是两个非常重要的概念,它们都是AOP中的切点。因此,JoinPoint和ProceedingJoinPoint的区别在于,ProceedingJoinPoint包含了一个proceed()方法,该方法用于执行目标方法,而JoinPoint则不包含该方法。在编写AOP切面时,如果需要在目标方法执行前或执行后做一些处理,可以使用JoinPoint;如果需要在目标方法执行过程中做一些处理,可以使用ProceedingJoinPoint。

👳我亲爱的各位大佬们好😘😘😘
♨️本篇文章记录的为 SpringAOP 关键API详解 相关内容,适合在学Java的小白,帮助新手快速上手,也适合复习中,面试中的大佬🙉🙉🙉。
♨️如果文章有什么需要改进的地方还请大佬不吝赐教❤️🧡💛
👨‍🔧 个人主页 : 阿千弟
🔥 上期内容👉👉👉 : 2023年主流的选择仍是Feign, http客户端Feign还能再战

@[toc]
在这里插入图片描述

JoinPoint和ProceedingJoinPoint区别

在Spring AOP中,JoinPoint和ProceedingJoinPoint是两个非常重要的概念,它们都是AOP中的切点。

JoinPoint是指在程序执行过程中,可以插入切面的点。例如,在方法执行前、执行后、抛出异常时等都可以插入切面。JoinPoint包含了当前程序执行的上下文信息,例如方法名、参数、目标对象等。

ProceedingJoinPoint是JoinPoint的子接口,它是在方法执行过程中的某个特定点,例如方法执行前、执行后、抛出异常时等。ProceedingJoinPoint除了包含JoinPoint的所有信息外,还包含了一个proceed()方法,该方法用于执行目标方法。

因此,JoinPoint和ProceedingJoinPoint的区别在于,ProceedingJoinPoint包含了一个proceed()方法,该方法用于执行目标方法,而JoinPoint则不包含该方法。在编写AOP切面时,如果需要在目标方法执行前或执行后做一些处理,可以使用JoinPoint;如果需要在目标方法执行过程中做一些处理,可以使用ProceedingJoinPoint。

在这里插入图片描述

ProceedingJoinPoint

ProceedingJoinPoint是Spring AOP中的一个接口,它代表了一个连接点,即被拦截的方法。在AOP中,我们可以通过拦截连接点来实现对方法的增强。

ProceedingJoinPoint接口提供了以下方法:

  1. Object[] getArgs():获取连接点方法的参数数组。

  2. Signature getSignature():获取连接点方法的签名对象。

  3. Object getTarget():获取连接点所在的目标对象。

  4. Object proceed() throws Throwable:执行连接点方法,返回结果。

  5. String toString():打印出连接点的信息。

在AOP中,我们可以通过ProceedingJoinPoint接口的proceed()方法来执行连接点方法,并在方法执行前后进行一些操作,比如记录日志、检查权限等。同时,我们也可以通过getArgs()方法获取连接点方法的参数,通过getTarget()方法获取目标对象,从而实现更加灵活的增强操作。

需要注意的是,如果我们在拦截器中调用了proceed()方法,那么被拦截的方法就会被执行,如果不调用proceed()方法,那么被拦截的方法就不会被执行。因此,在使用ProceedingJoinPoint时,一定要注意调用proceed()方法的时机。

使用

ProceedingJoinPoint包含了连接点的所有信息,包括目标对象、目标方法、方法参数等。

在使用Spring AOP时,我们可以通过ProceedingJoinPoint来获取连接点的信息,并在切面中对目标方法进行增强。具体使用方法如下:

  1. 在切面方法中声明ProceedingJoinPoint参数。
@Aspect
@Component
public class MyAspect {
   
   
    @Around("execution(* com.example.demo.service.UserService.*(..))")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
   
   
        // 切面逻辑
        Object result = joinPoint.proceed(); // 调用目标方法
        // 切面逻辑
        return result;
    }
}
  1. 在切面方法中调用ProceedingJoinPoint的proceed()方法来调用目标方法。

  2. 可以通过ProceedingJoinPoint的getArgs()方法获取目标方法的参数。

@Around("execution(* com.example.demo.service.UserService.addUser(..))")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
   
   
    Object[] args = joinPoint.getArgs(); // 获取目标方法的参数
    // 切面逻辑
    Object result = joinPoint.proceed(); // 调用目标方法
    // 切面逻辑
    return result;
}
  1. 可以通过ProceedingJoinPoint的getTarget()方法获取目标对象。
@Around("execution(* com.example.demo.service.UserService.addUser(..))")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
   
   
    Object target = joinPoint.getTarget(); // 获取目标对象
    // 切面逻辑
    Object result = joinPoint.proceed(); // 调用目标方法
    // 切面逻辑
    return result;
}
  1. 可以通过ProceedingJoinPoint的getSignature()方法获取目标方法的签名。
@Around("execution(* com.example.demo.service.UserService.addUser(..))")
public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
   
   
    Signature signature = joinPoint.getSignature(); // 获取目标方法的签名
    // 切面逻辑
    Object result = joinPoint.proceed(); // 调用目标方法
    // 切面逻辑
    return result;
}

在这里插入图片描述

getSignature

总之,ProceedingJoinPoint是Spring AOP中非常重要的一个接口,它提供了丰富的方法来获取连接点的信息,并在切面中对目标方法进行增强。

getSignature()方法是ProceedingJoinPoint接口中的一个方法,用于获取连接点的签名信息。

连接点的签名信息包括方法名、参数类型、返回类型等。通过getSignature()方法可以获取到一个Signature对象,该对象包含了连接点的签名信息。Signature是一个接口,它有两个子接口:MethodSignature和ConstructorSignature。MethodSignature用于表示方法的签名信息,ConstructorSignature用于表示构造函数的签名信息。

在使用getSignature()方法时,需要先将ProceedingJoinPoint对象转换为MethodSignature或ConstructorSignature对象,然后再调用相应的方法获取签名信息。例如,可以使用以下代码获取连接点的方法名:

MethodSignature signature = (MethodSignature) joinPoint.getSignature();
String methodName = signature.getName();

在上述代码中,首先将joinPoint对象转换为MethodSignature对象,然后通过getName()方法获取方法名。

除了获取方法名,还可以通过getDeclaringTypeName()方法获取方法所在类的全限定名,通过getParameterTypes()方法获取方法的参数类型数组,通过getReturnType()方法获取方法的返回类型等。

总之,通过getSignature()方法可以获取连接点的签名信息,从而在切面中对连接点进行更加精细的控制和处理。

@Aspect
@Component
@Slf4j
public class XXXAspect {
   
   

    @Resource
    private SaveLogMapper saveLogMapper;

    /**
     * 设置保存菜单点击记录切入点,在注解的位置切入代码
     */
    @Pointcut("@annotation(com.aqd.Log)")
    public void saveQueryUserPortraitLogPointCut() {
   
   

    }

    @Before("saveLogPointCut()")
    public void saveQueryUserPortraitLog(JoinPoint joinPoint) {
   
   
        //----------------单纯的知道哪个类哪个方法进的切面,用于记录start add by zxx -------------------------
        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        String className = joinPoint.getTarget().getClass().getName();
        String methodName = methodSignature.getMethod().getName();
        //----------------单纯的知道哪个类哪个方法进的切面,用于记录start add by zxx -------------------------

        // 获取RequestAttributes,这个RequestContextHolder是Springmvc提供来获得请求的东西
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        // 从获取RequestAttributes中获取HttpServletRequest的信息
        HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
        //从请求的参数中获取被查询的手机号 add by zxx 2021/09/14
        String protraitQueryedNo = request.getParameter("protraitQueryedNo");
        JSONObject userInfo =  ((JSONObject) JSON.toJSON(request.getSession().getAttribute("userInfo")));
        String userId =userInfo.getString("userId");
        //userAccessPermissions
        String sessionId = request.getSession().getId();
        //客户端ip
        String clientAddress =request.getRemoteAddr();
        //客户端端口
        String clientPort = String.valueOf(request.getRemotePort());
        //服务端IP
        String serverAddress = request.getLocalAddr();
        //服务端端口
        String serverPort = String.valueOf(request.getLocalPort());
        log.info("[saveLog]className:{},methodName:{}-start to saveLog,userId:{},protraitQueryedNo:{}!!",
                className, methodName,userId,protraitQueryedNo);
    }
}

在这里插入图片描述

如果这篇【文章】有帮助到你💖,希望可以给我点个赞👍,创作不易,如果有对Java后端或者对spring感兴趣的朋友,请多多关注💖💖💖
👨‍🔧 个人主页 : 阿千弟

目录
相关文章
|
7月前
|
API
05JavaWeb基础 - Servlet的相关API
05JavaWeb基础 - Servlet的相关API
20 0
|
3月前
|
前端开发 Java API
构建强大的RESTful API:@RestController与@Controller的对比与应用
构建强大的RESTful API:@RestController与@Controller的对比与应用
35 0
|
4月前
|
JSON Java 应用服务中间件
|
10月前
|
NoSQL Java API
SpringBoot API 接口防刷
顾名思义,想让某个接口某个人在某段时间内只能请求N次。 在项目中比较常见的问题也有,那就是连点按钮导致请求多次,以前在web端有表单重复提交,可以通过token 来解决。 除了上面的方法外,前后端配合的方法。现在全部由后端来控制。
132 0
|
11月前
|
JSON 编解码 前端开发
【JavaEE】Servlet的API详解
【JavaEE】Servlet的API详解
73 0
|
JSON 前端开发 JavaScript
Servlet API详解
本文我们主要介绍Servlet里的关键API,也就是HttpServlet、HttpServletRequest、HttpServletResponse这三个类中一些方法的使用。
119 0
Servlet API详解
|
Java API Maven
springMvc31-原生api
springMvc31-原生api
37 0
springMvc31-原生api
|
SQL Java 数据库连接
Hibernate的Api使用
Hibernate的Api使用
|
Java API
Java反射机制API
反射(Reflection)是程序的自我分析能力,通过反射可以确定类有哪些方法、有哪些构造方法以及有 哪些成员变量。Java语言提供了反射机制,通过反射机制能够动态读取一个类的信息;能够在运行时 动态加载类,而不是在编译期。反射可以应用于框架开发,它能够从配置文件中读取配置信息动态加 载类、创建对象,以及调用方法和成员变量。