Spring AOP简述

在 Spring AOP 中,核心概念包括 切面(Aspect)连接点(JoinPoint)通知(Advice)切点(Pointcut)目标对象(Target Object)代理(Proxy)

概念描述
切面(Aspect) 抽象出的功能模块,包含横切逻辑的实现,比如日志、事务等。
通知(Advice) 具体的横切逻辑。通知分为前置、后置、环绕等类型。
切点(Pointcut) 定义通知应该织入的位置。一般是方法的执行点。
连接点(JoinPoint) 指可以应用通知的代码位置,通常是方法的执行点。
目标对象(Target Object) 被 AOP 代理的对象。目标对象是切点执行的方法所在的对象。
代理(Proxy) 代理对象,在运行时通过动态代理机制生成,执行目标方法。

1️⃣ 切面(Aspect)

  • 定义:切面是 AOP 的核心概念,表示一个模块化的横切关注点(比如日志、事务等),它将不同功能(如日志、缓存、权限)从具体的业务逻辑中解耦出来。通常一个切面会包含多个通知(Advice)和一个切点(Pointcut)。

    源码场景解释

    • 比如你在代码中有如下 LoggingAspect 类,这个类就是一个切面(Aspect)。

    • 代码示例:

      @Aspect 
      public class LoggingAspect { // 这里就是切面,它包含了切点和通知 }

       

2️⃣ 通知(Advice)

  • 定义:通知是切面中实现的具体横切逻辑,它定义了在某个特定的连接点(方法执行时)执行的代码。通知有多种类型,常见的有:前置通知、后置通知、环绕通知、异常通知等。

    源码场景解释

    • LoggingAspect 类中,前置通知 logBefore() 和后置通知 logAfter() 是通知的实例。

    • 代码示例:

      @Before("execution(* com.example.service.*.*(..))")
      public void logBefore() {
          System.out.println("方法执行前的日志");
      }
      
      @After("execution(* com.example.service.*.*(..))")
      public void logAfter() {
          System.out.println("方法执行后的日志");
      }

       

    • 这里 logBefore()logAfter() 都是通知,它们在方法执行前后分别执行。

3️⃣ 切点(Pointcut)

  • 定义:切点是一个表达式,用来定义通知应当作用于哪些方法。可以理解为通知的“目标”,即哪些方法将会被“织入”通知。

    源码场景解释

    • execution(* com.example.service.*.*(..)) 是一个切点表达式,它匹配 com.example.service 包下所有类的所有方法。

    • 代码示例:

      @Before("execution(* com.example.service.*.*(..))")
      public void logBefore() {
          System.out.println("方法执行前的日志");
      }

       

    • 这里的 execution(* com.example.service.*.*(..)) 就是切点,表示匹配 com.example.service 包下所有的方法。

4️⃣ 连接点(JoinPoint)

  • 定义:连接点是程序中可以应用通知的一个位置,通常是方法的执行点。AOP 在这些连接点织入通知。

    源码场景解释

    • logAround() 方法中,我们通过 ProceedingJoinPoint 获取目标方法的信息,可以理解为方法执行的连接点。

    • 代码示例:

      @Around("execution(* com.example.service.*.*(..))")
      public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
          System.out.println("方法执行前的日志");
          Object result = joinPoint.proceed(); // 执行目标方法
          System.out.println("方法执行后的日志");
          return result;
      }

       

    • joinPoint.proceed() 就是连接点,它代表的是目标方法的执行。通过 joinPoint 可以访问目标方法的相关信息。

5️⃣ 目标对象(Target Object)

  • 定义:目标对象是 AOP 代理的对象,包含了最终执行的业务逻辑。AOP 会在目标对象的方法上织入通知。

    源码场景解释

    • 假设你有一个 UserService 类,它是被 AOP 代理的对象,所有的业务方法执行都会受到切面中通知的影响。

    • 代码示例:

      @Component
      public class UserService {
          public void addUser() {
              System.out.println("添加用户...");
          }
      }

       

    • 这里的 UserService 就是目标对象,AOP 会在这个类的方法上织入通知。

6️⃣ 代理(Proxy)

  • 定义:代理对象是在运行时动态创建的对象,它会执行目标方法,并在执行前后织入通知。Spring 默认使用 JDK 动态代理和 CGLIB 动态代理两种方式。

    源码场景解释

    • 代理对象是通过 Spring AOP 的动态代理机制创建的。对于实现了接口的目标对象,Spring 使用 JDK 动态代理;对于没有实现接口的目标对象,Spring 使用 CGLIB 代理。

    • 代码示例:

      @Component
      public class UserService {
          public void addUser() {
              System.out.println("添加用户...");
          }
      }

       

    • 假设我们有一个 UserService 类,Spring 会为它生成代理对象,代理对象会在目标方法执行前后,执行切面中的通知逻辑。

 
posted @ 2025-04-05 11:20  ~落辰~  阅读(53)  评论(0)    收藏  举报