相关推荐recommended
springboot实现aop
作者:mmseoamin日期:2024-02-20

目录

  • AOP(术语)
  • 引入依赖
  • 实现步骤
  • 测试验证
  • 感谢阅读

    AOP(术语)

    1. 连接点

      类里面哪些方法可以增强,这些点被称为连接点

    2. 切入点

      实际被真正增强的方法

    3. 通知(增强)

      实际增强的逻辑部分称为通知(增强)

      通知(增强)有多种类型

    • 前置通知–@Before
    • 后置通知–@After
    • 环绕通知–@Around
    • 异常通知–@AfterThrowing
    • 最终通知–@AfterReturning

      切面(是动作)–

      把通知(增强)应用到切入点过程

      引入依赖

      
              
                  org.springframework.boot
                  spring-boot-starter
              
              
                  org.springframework.boot
                  spring-boot-starter-web
              
              
                  org.springframework.boot
                  spring-boot-starter-aop
              
          
      

      实现步骤

      1. 新建一个注解类,用于后面做切入点
      @Retention(value = RetentionPolicy.RUNTIME)
      @Target(ElementType.METHOD)
      public @interface Authorization {
      }
      
      1. 建一个切面类
      @Aspect
      @Component
      public class AuthAspect {
          /**
           * 定义了一个切点
           * 这里的路径填自定义注解的全路径
           */
          @Pointcut("@annotation(com.zhuyh.studytest.spring5.aop.Authorization)")
          public void authornizeCut() {
          }
          @Before("authornizeCut()")
          public void cutProcess(JoinPoint joinPoint) {
              MethodSignature signature = (MethodSignature) joinPoint.getSignature();
              Method method = signature.getMethod();
              System.out.println("AOP开始拦截, 当前拦截的方法名: " + method.getName());
          }
          @After("authornizeCut()")
          public void after(JoinPoint joinPoint) {
              MethodSignature signature = (MethodSignature) joinPoint.getSignature();
              Method method = signature.getMethod();
              System.out.println("AOP执行的方法 :" + method.getName() + " 执行完了");
          }
          @Around("authornizeCut()")
          public Object testCutAround(ProceedingJoinPoint joinPoint) throws Throwable {
              System.out.println("AOP拦截开始进入环绕通知.......");
              Object proceed = joinPoint.proceed();
              System.out.println("准备退出环绕......");
              return proceed;
          }
          /**
           * returning属性指定连接点方法返回的结果放置在result变量中
           *
           * @param joinPoint 连接点
           * @param result    返回结果
           */
          @AfterReturning(value = "authornizeCut()", returning = "result")
          public void afterReturn(JoinPoint joinPoint, Object result) {
              MethodSignature signature = (MethodSignature) joinPoint.getSignature();
              Method method = signature.getMethod();
              System.out.println("AOP拦截的方法执行成功, 进入返回通知拦截, 方法名为: " + method.getName() + ", 返回结果为: " + result.toString());
          }
          @AfterThrowing(value = "authornizeCut()", throwing = "e")
          public void afterThrow(JoinPoint joinPoint, Exception e) {
              MethodSignature signature = (MethodSignature) joinPoint.getSignature();
              Method method = signature.getMethod();
              System.out.println("AOP进入方法异常拦截, 方法名为: " + method.getName() + ", 异常信息为: " + e.getMessage());
          }
      }
      
      1. 来一个Controller作为请求被代理的对象
      @RestController
      @RequestMapping("/company")
      public class CompanyController {
          @GetMapping("/aopTest")
          @Authorization
          public Object aopTest(@RequestParam String name){
              //远程调用
              System.out.println("执行接口name:" + name);
              // int n = 1/0;
              return "成功了-----" + name;
          }
      }
      
      1. 启动类启动项目
      @SpringBootApplication
      public class StudyTestApplication {
          public static void main(String[] args) {
              SpringApplication.run(StudyTestApplication.class, args);
          }
      }
      

      测试验证

      1. 浏览器或者api调用工具调接口

        springboot实现aop,在这里插入图片描述,第1张

      2. 控制台打印
      AOP拦截开始进入环绕通知.......
      AOP开始拦截, 当前拦截的方法名: aopTest
      执行接口name:zhuyh
      AOP拦截的方法执行成功, 进入返回通知拦截, 方法名为: aopTest, 返回结果为: 成功了-----zhuyh
      AOP执行的方法 :aopTest 执行完了
      准备退出环绕......
      
      1. Controller加入一个异常 int i=1/0; 重启项目再次调用

        异常通知打印了 / by zero

      AOP拦截开始进入环绕通知.......
      AOP开始拦截, 当前拦截的方法名: aopTest
      执行接口name:zhuyh
      AOP进入方法异常拦截, 方法名为: aopTest, 异常信息为: / by zero
      AOP执行的方法 :aopTest 执行完了
      2024-01-24 16:50:10.477 ERROR 4888 --- [nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.ArithmeticException: / by zero] with root cause
      java.lang.ArithmeticException: / by zero
      	at com.zhuyh.studytest.spring5.aop.CompanyController.aopTest(CompanyController.java:16) ~[classes/:na]
      

      感谢阅读

      谢谢您的陪伴! 如果您有任何问题、建议或想要了解的特定主题,请随时在评论中告诉我们。期待与您共同探索java,共同提升我们的Java开发技能!