AOP进阶-通知类型

通知类型

  • @Around

    • 环绕通知,此注解标注的通知方法在目标方法前后都被执行,可以在目标方法执行前后插入自定义的逻辑,例如性能监控、事务管理等。环绕通知可以完全控制目标方法的执行,可以决定是否继续执行目标方法,以及如何处理目标方法的返回值。
  • @Before

    • 前置通知,此注解标注的通知方法在目标方法前被执行,可以在方法执行前插入一些逻辑,例如参数校验、权限检查等。
  • @After

    • 后置通知,此注解标注的通知方法在目标方法后被执行,无论是否有异常都会被执行,可以在方法执行后进行一些清理工作,例如释放资源、记录日志等。
  • @AfterReturning

    • 返回后通知,此注解标注的通知方法在目标方法后被执行,有异常不会执行,可以获取目标方法的返回值并进行处理,例如对返回结果进行日志记录、数据处理等。
  • @AfterThrowing

    • 异常后通知,此注解标注的通知方法发送异常后执行,可以捕获目标方法抛出的异常,并进行相应的处理,例如异常日志记录、异常处理等。

具体示例代码

  • package com.example.tlias.AOP;
    
    import lombok.extern.slf4j.Slf4j;
    import org.aspectj.lang.ProceedingJoinPoint;
    import org.aspectj.lang.annotation.*;
    import org.springframework.stereotype.Component;
    
    @Slf4j
    @Component
    @Aspect
    public class TestAdvice {
        @Before("execution(* com.example.tlias.service.impl.EmpServiceImpl.*(..))")
        public void before() {
            log.info("before....");
        }
    
        @After("execution(* com.example.tlias.service.impl.EmpServiceImpl.*(..))")
        public void after() {
            log.info("after....");
        }
    
        @Around("execution(* com.example.tlias.service.impl.EmpServiceImpl.*(..))")
        public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
            log.info("around before...");
            Object result = proceedingJoinPoint.proceed();
            log.info("around after...");
            return result;
        }
    
        @AfterReturning("execution(* com.example.tlias.service.impl.EmpServiceImpl.*(..))")
        public void AfterReturning() {
            log.info("AfterReturning......");
        }
    
        @AfterThrowing("execution(* com.example.tlias.service.impl.EmpServiceImpl.*(..))")
        public void AfterThrowing() {
            log.info("AfterThrowing......");
        }
    }
    
  • 对上述代码进行优化,对于切入点表达式进行统一设置,使用注解@Pointcut
    • 具体代码如下:
      • package com.example.tlias.AOP;
        
        import lombok.extern.slf4j.Slf4j;
        import org.aspectj.lang.ProceedingJoinPoint;
        import org.aspectj.lang.annotation.*;
        import org.springframework.stereotype.Component;
        
        @Slf4j
        @Component
        @Aspect
        public class TestAdvice {
            @Pointcut("execution(* com.example.tlias.service.impl.EmpServiceImpl.*(..))")
            public void PointCut(){}
            @Before("PointCut()")
            public void before() {
                log.info("before....");
            }
        
            @After("PointCut()")
            public void after() {
                log.info("after....");
            }
        
            @Around("PointCut()")
            public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
                log.info("around before...");
                Object result = proceedingJoinPoint.proceed();
                log.info("around after...");
                return result;
            }
        
            @AfterReturning("PointCut()")
            public void AfterReturning() {
                log.info("AfterReturning......");
            }
        
            @AfterThrowing("PointCut()")
            public void AfterThrowing() {
                log.info("AfterThrowing......");
            }
        }
        

注意事项

  • @Around环绕通知需要自己调用ProceedingJoinPoint.proceed()来让原始方法执行,其它通知不需要考虑目标方法的执行
  • @Around环绕通知方法的返回值,必须指定为Object,来接受原始方法的返回值
  • @Pointcut该注解的作用是将公共的切点表达式抽取出来,需要用到时引用该切点表达式即可

你可能感兴趣的:(Java,Web学习跟踪笔记,java,开发语言)