一篇文章帶你搞定 SpringBoot 整合 AOP

對於 AOP 的知識在 Spring 學習章節已經進行過學習:一篇文章幫你搞定 Spring

本篇文章主要講述如何在 SpringBoot 中使用 AOP

示例場景:比如項目已經上線,某個環節運行速度特別慢,需要對其單獨打印日誌測試一下,挨個去改很顯然不靠譜,因此可以藉助AOP,將該段代碼嵌入到業務中,檢測完成後,再移出掉即可。

一、前期配置

在這裏插入圖片描述
同時需要我們pom 中引入 aop 依賴

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

二、前置/後置/異常/最終通知的實現

這裏的實現類似於:一篇文章幫你搞定 Spring 基於註解的AOP配置
目錄結構:
在這裏插入圖片描述
UserService:

@Service
public class UserService {
    public String getUsernameById(Integer id) {
        System.out.println("UserService 執行 getUsernameById >>>> " + id);
        return "Yolo";
    }

    public void getUsernameError(String name) {
        System.out.println("UserService 執行 getUsernameByName >>>> " + name);
        int i = 3/0;
    }
}

UserController:

@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    UserService userService;

    @GetMapping("/id")
    public String getUserById(int id) {
        return userService.getUsernameById(id);
    }

    @GetMapping("/error")
    public void getError(){
        System.out.println("進來了。。。。。。");
        userService.getUsernameError("yolo");
    }
}

LogComponent

@Component
@Aspect
public class LogComponent {
    /**
     * 對com.yolo.aop.service包下的所有方法進行增強
     */
    @Pointcut("execution(* com.yolo.aop.service.*.*(..))")
    public void pc1() {
    }

    //前置通知
    @Before(value = "pc1()")
    public void before(JoinPoint jp) {
        String name = jp.getSignature().getName();
        System.out.println("前置通知 >>> " + name);
    }

    //後置通知
    @AfterReturning(value = "pc1()", returning = "result")
    public void afterReturning(JoinPoint jp, Object result) {
        String name = jp.getSignature().getName();
        System.out.println("後置通知 >>> " + name + " >>> " + result);
    }

    //異常通知
    @AfterThrowing(value = "pc1()", throwing = "e")
    public void afterThrowing(JoinPoint jp, Exception e) {
        String name = jp.getSignature().getName();
        System.out.println("異常通知 >>> " + name + " >>> " + e.getMessage());
    }

    //最終通知
    @After(value = "pc1()")
    public void after(JoinPoint jp) {
        String name = jp.getSignature().getName();
        System.out.println("最終通知 >>> " + name);
    }
}

在這裏插入圖片描述
測試異常通知:
在這裏插入圖片描述

三、環繞通知的實現

@Component
@Aspect
public class LogComponent {
    /**
     * 對com.yolo.aop.service包下的所有方法進行增強
     */
    @Pointcut("execution(* com.yolo.aop.service.*.*(..))")
    public void pc1() {
    }

    //環繞通知
    @Around("pc1()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        Object rtValue = null;
        try {
            //得到方法執行所需的參數
            Object[] args = pjp.getArgs();
            System.out.println("args >>> " + args);
            System.out.println("Logger類中的aroundPringLog方法開始記錄日誌了。。。前置");
            //明確調用業務層方法(切入點方法)
            rtValue = pjp.proceed(args);
            System.out.println("rtValue >>> " + rtValue);
            System.out.println("Logger類中的aroundPringLog方法開始記錄日誌了。。。後置");

            return rtValue;
        } catch (Throwable t) {
            System.out.println("Logger類中的aroundPringLog方法開始記錄日誌了。。。異常");
            throw new RuntimeException(t);
        } finally {
            System.out.println("Logger類中的aroundPringLog方法開始記錄日誌了。。。最終");
        }
    }
}

在這裏插入圖片描述
測試異常通知:
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章