【Spring】AOP——通知(Advice)

【Spring】AOP——通知(Advice)

码农世界 2024-05-30 后端 92 次浏览 0个评论

1、通知(Advice)

1.1简介

  • 在AOP中,通知(Advice)是切面(Aspect)中的一部分,用于定义在连接点(Joinpoint)处应该执行的操作。
  • 通知类型可以在AOP框架中配置和使用,以便在运行时动态地将代码切入到类的指定方法、指定位置上。
  • 通过AOP,开发人员可以将日志记录、性能统计、安全控制、事务处理等代码从业务逻辑代码中划分出来,并独立到非指导业务逻辑的方法中,从而提高程序的可重用性和开发效率。

    1.2常见的通知类型

    • 前置通知(Before Advice):在目标方法执行之前执行的通知,无法阻止方法的继续执行(除非它抛出一个异常)。
    • 后置通知(After Returning Advice):在目标方法成功执行之后执行的通知。如果目标方法通过抛出异常退出,则不会执行此类型的通知。
    • 异常通知(After Throwing Advice):在目标方法通过抛出异常退出时执行的通知。通常用于记录异常信息或进行异常处理。
    • 最终通知(After (finally) Advice):无论目标方法通过何种方式退出(正常返回或异常退出),该通知都会执行。它类似于Java语言中的finally块。
    • 环绕通知(Around Advice):环绕通知是最强大的通知类型,它将目标方法封装起来,可以在方法调用之前和之后自定义行为,甚至可以完全控制是否调用目标方法。环绕通知可以手动调用切入点方法并对其进行增强,从而实现更复杂的逻辑处理。

      2、代码举例

      在Spring AOP中,我们通常使用AspectJ的注解来定义通知。以下是用Spring AOP和AspectJ注解方式示范五种通知类型的示例代码:

      首先,我们需要一个目标接口和一个实现类:

      // 目标接口  
      public interface MyService {  
          void doSomething();  
          void doSomethingElse() throws Exception;  
      }  
        
      // 目标接口实现类  
      @Service  
      public class MyServiceImpl implements MyService {  
          @Override  
          public void doSomething() {  
              System.out.println("Doing something...");  
          }  
        
          @Override  
          public void doSomethingElse() throws Exception {  
              System.out.println("Doing something else...");  
              throw new Exception("An exception occurred!");  
          }  
      }

      创建一个切面类,并使用AspectJ的注解来定义五种通知:

      @Aspect  
      @Component  
      public class MyAspect {  
        
          // 前置通知  
          @Before("execution(* com.example.demo.MyService.doSomething(..))")  
          public void beforeAdvice() {  
              System.out.println("Before doSomething is executed.");  
          }  
        
          // 后置通知(返回后)  
          @AfterReturning(pointcut = "execution(* com.example.demo.MyService.doSomething(..))", returning = "result")  
          public void afterReturningAdvice(JoinPoint joinPoint, Object result) {  
              System.out.println("After doSomething is executed. Result: " + result);  
              // 注意:这里result参数只有在目标方法有返回值时才有意义  
          }  
        
          // 异常通知  
          @AfterThrowing(pointcut = "execution(* com.example.demo.MyService.doSomethingElse(..))", throwing = "ex")  
          public void afterThrowingAdvice(JoinPoint joinPoint, Exception ex) {  
              System.out.println("Exception occurred in doSomethingElse: " + ex.getMessage());  
          }  
        
          // 最终通知(无论成功还是异常)  
          @After("execution(* com.example.demo.MyService.*(..))")  
          public void afterAdvice(JoinPoint joinPoint) {  
              System.out.println("After method is executed: " + joinPoint.getSignature().getName());  
          }  
        
          // 环绕通知  
          @Around("execution(* com.example.demo.MyService.doSomething(..))")  
          public Object aroundAdvice(ProceedingJoinPoint joinPoint) throws Throwable {  
              System.out.println("Before doSomething is executed (around advice).");  
              Object result = joinPoint.proceed(); // 调用目标方法  
              System.out.println("After doSomething is executed (around advice). Result: " + result);  
              return result;  
          }  
      }

      在Spring配置中启用AspectJ自动代理,通过@EnableAspectJAutoProxy注解在配置类上完成:

      @Configuration  
      @EnableAspectJAutoProxy  
      public class AppConfig {  
          // ... 其他配置 ...  
      }

       

转载请注明来自码农世界,本文标题:《【Spring】AOP——通知(Advice)》

百度分享代码,如果开启HTTPS请参考李洋个人博客
每一天,每一秒,你所做的决定都会改变你的人生!

发表评论

快捷回复:

评论列表 (暂无评论,92人围观)参与讨论

还没有评论,来说两句吧...

Top