首页 > 其他分享 >【Spring】AOP进阶-JoinPoint和ProceedingJoinPoint详解

【Spring】AOP进阶-JoinPoint和ProceedingJoinPoint详解

时间:2024-04-14 16:33:24浏览次数:17  
标签:JoinPoint 进阶 Spring ProceedingJoinPoint 获取 AOP joinPoint 方法

2024-04-14

1. 前言

Spring AOP中,JoinPoint和ProceedingJoinPoint都是关键的接口,用于在切面中获取方法的相关信息以及控制方法的执行。它们的主要区别在于它们在AOP通知中的使用方式和功能。

2. JoinPoint简介

Joinpoint是面向切面编程(AOP)中的一个重要概念,指的是在应用程序执行过程中可以被拦截的特定点。在AOP中,Joinpoint代表了程序执行的某个具体位置,比如方法的调用、异常的抛出等。AOP框架通过拦截这些Joinpoint来插入额外的逻辑,实现横切关注点的功能。

 

⭐我们可以通过JoinPoint获取到除了异常参数对象和返回值之外的所有信息

示例:

可以看到JoinPoint有很多方法.我们可以使用断点调试来看这些方法是干什么用的.

在方法的参数中添加JoinPoint参数

 

 


打上断点,进行调试,可以看到JoinPoint相关参数

 

 

 

在这里可以调试相应的方法

 

 例如:

 

当然如果觉得麻烦,也可以直接写代码进行调试,如:

 

JoinPoint相应的方法都可以通过这种方式来调试.由于篇幅原因这里就不过多演示了

3. 获取被增强方法的相关信息

常用方法如下:

获取方法调用时,传入的参数

Object[] args = joinPoint.getArgs();

获取被通知的目标对象

Object target = joinPoint.getTarget();

获取代理方法的信息

MethodSignature signature = (MethodSignature) joinPoint.getSignature(); // 获取代理方法的信息
String methodName = signature.getName(); // 获取方法名
Class<?> returnType = signature.getReturnType(); // 获取返回类型
Class<?>[] parameterTypes = signature.getParameterTypes(); // 获取参数类型数组

在这个示例中,我们首先使用joinPoint.getSignature() 方法获取代理方法的信息,然后将其转换为MethodSignature类型的对象。接着我们可以通过MethodSignature对象的方法获取方法名、返回类型、参数类型等信息,用于在通知中进行处理

获取增强方法中返回值

@AfterReturning(value = "point()",returning = "ret")
public void methodAfterReturning(JoinPoint joinPoint, Object ret){
    System.out.println("AfterReturning");
}

 

获取增强方法中的异常对象

@AfterThrowing(value = "point()",throwing = "e")
public void methodAfterThrowing(JoinPoint joinPoint,Throwable e){
    System.out.println("AfterThrowing");
}

⭐注意注解中的写法,加了一些参数,同时要将目标方法赋值给value,此外获取增强方法中的返回值,并不一定是要Object类型的,可根据需求自行调整

总的来说,Joinpoint代表了AOP中能够被拦截的程序执行点,通过拦截这些Joinpoint来实现横切关注点的功能。在Spring的AOP中,理解和使用Joinpoint是非常重要的。

以上的JoinPoint都是用在添加@Before,@AfterReturning,@After,@AfterThrowing这四个注解的方法上的,而环绕通知则不同,使用的是ProceedingJoinPoint

4. ProceedingJoinPoint简介

在Spring AOP中,ProceedingJoinPoint是JoinPoint的子接口,它专门用于环绕通知(Around advice)。ProceedingJoinPoint包含了被通知方法的执行信息,同时可以访问被通知方法的信息和参数。可以通过使用ProceedingJoinPoint接口来实现更加灵活和精细的环绕通知逻辑。

5. 获取环绕通知方法的相关信息

ProceedingJoinPoint接口提供了以下常用方法:

  1. proceed():这是ProceedingJoinPoint接口中最重要的方法。在环绕通知中,调用proceed()方法会继续执行被通知的方法。如果环绕通知中不调用proceed()方法,被通知的方法将不会执行。
@Around("execution(* com.example.service.*.*(..))")
public Object aroundMethod(ProceedingJoinPoint joinPoint) throws Throwable {
    // 执行前置逻辑
    Object result = joinPoint.proceed(); // 继续执行被通知的方法
    // 执行后置逻辑
    return result;
}

注意joinPoint.proceed()方法是可能有返回值的,返回值类型可能有很多,可以直接设置为Object类型

  1. getArgs():获取被通知方法的参数数组。
Object[] args = joinPoint.getArgs();
  1. getTarget():获取被通知的目标对象。
Object target = joinPoint.getTarget();

ProceedingJoinPoint接口的主要作用是在环绕通知中控制被通知方法的执行,同时可以访问被通知方法的信息和参数。开发人员可以通过使用ProceedingJoinPoint接口来实现更加灵活和精细的环绕通知逻辑。

6. 总结

JoinPoint用于获取方法的信息,而ProceedingJoinPoint除了能获取方法的信息外,还可以控制方法的执行,这使得它在环绕通知中非常有用。在AOP的实践中,开发人员需要理解这两个接口的使用方式,并根据具体的需求选择合适的接口来实现横切关注点的功能。

 

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。

原文链接:https://blog.csdn.net/m0_63463510/article/details/134437856

 

标签:JoinPoint,进阶,Spring,ProceedingJoinPoint,获取,AOP,joinPoint,方法
From: https://www.cnblogs.com/isme-zjh/p/18134299

相关文章

  • SpringBoot项目中对定义的多个BeanPostProcessor排序
    前言BeanPostProcessor是Spring提供的一种扩展机制,可以让我们在bean初始化前后做一些额外的操作,Spring中的@Async,@Scheduled,@RabbitHandler等注解的底层实现都是BeanPostProcessor在起作用,如RabbitListenerAnnotationBeanPostProcessor。代码示例@Configurationpub......
  • java: 无法访问org.mybatis.spring.annotation.MapperScan、类文件具有错误的版本 61.
    使用的Mybatis-spring依赖的版本3.0.1太高,将版本改为2.2.2<dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.2.2</version></dependency><depende......
  • Hystrix应用:如何在Spring Boot中使用Hystrix?
    引言在微服务架构的发展过程中,面对复杂的服务依赖和不可预见的系统故障,如何提升系统的容错能力成为了一个非常急迫且重要的能力。由Netflix(网飞)公司开发的Hystrix库,作为一个服务熔断和隔离框架,能有效地帮助开发者控制服务间的交互,防止系统间的级联故障。本文将带你详细了解......
  • 小端对齐+大端对齐进阶版本V3.0
    当涉及到多字节的数据类型(如uint16_t、uint32_t等)时,字节在内存中的存储顺序会影响到数据的解释方式。这个存储顺序可以分为两种:大端对齐(BigEndian)和小端对齐(LittleEndian)。大端对齐(BigEndian):在大端对齐中,数据的高字节(MostSignificantByte,MSB)存储在内存的低地址,而数据的低......
  • Spring学习笔记
    一、Spring启示录阅读以下代码:packagecom.powernode.oa.controller;importcom.powernode.oa.service.UserService;importcom.powernode.oa.service.impl.UserServiceImpl;publicclassUserController{privateUserServiceuserService=newUserServiceImpl();......
  • Springboot集成WebSocket实现智能聊天【Demo】
    背景openai目前越来越流行,其他ai产业也随之而来,偶然翻到openai接口文档,就想着可以调用接口实现智能聊天,接下来就写写我怎么接入websocket的过程,文笔不佳,谅解。接入WebSocket1.webSocket依赖<dependency><groupId>org.springframework.boot</groupId><artifactId......
  • SpringBoot项目中对定义的多个Aspect类排序
    代码示例@ConfigurationpublicclassAspectConfig{@Aspect@Component@Order(Ordered.HIGHEST_PRECEDENCE)publicstaticclassLogAspect{@Pointcut("execution(public*com.imooc.spring.web..*.*(..))")publicvoidwe......
  • SpringBoot中的Jetty使用及分析
    前言和Tomcat类似,Jetty也是一个Web应用服务器,相对于Tomcat,Jetty更加轻量、更加简易、更加灵活。今天通过代码来简单分析下SpringBoot中是如何启动Jetty的。Jetty简介使用importjava.io.File;importjava.io.IOException;importjava.net.InetAddress;import......
  • SpringBoot使用 nacos 会默认加载项目名配置文件
    问题描述boostrap.yml配置如下spring:application:name:cnblogscloud:nacos:config:server-addr:http://ip:8848namespace:d8b0df04-aa58-4a5b-b582-7d133b9e8b2c#命名空间IDfile-extension:yamlusern......
  • springboot集成redis
    首先引入依赖<!--redis坐标--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency>在yml中引入redis数据库spring......