天天看點

SpringBoot內建AOP學習筆記

SpringBoot內建AOP學習筆記

版本說明

spring.boot=2.2.3.RELEASE      

總的說明

無異常執行順序:around before ——> before ——> 攔截的方法 ——> around after ——> after  ——> afterReturning
有異常執行順序:around before ——> before ——> 攔截的方法  ——> after  ——> afterThrowing      
  • around before :環繞通知前
  • around after :環繞通知後
  • before : 前置通知
  • after : 後置通知
  • afterReturning :傳回後通知
  • afterThrowing :異常通知

實戰演練

pom.xml

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

Controller

package top.simba1949.controller;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
 * @Author Theodore
 * @Date 2020/1/19 16:25
 */
@Slf4j
@RestController
@RequestMapping("user")
public class UserController {
    @GetMapping
    public String sayHello(@RequestParam Integer uid){
        log.info("uid is {}", uid);
//        int i = 1/0;
        return "Hello";
    }
}      

切面

package top.simba1949.aop;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
/**
 * 定義切面
 * 無異常執行順序:around before ——> before ——> 攔截的方法 ——> around after ——> after  ——> afterReturning
 * 有異常執行順序:around before ——> before ——> 攔截的方法  ——> after  ——> afterThrowing
 * @Author Theodore
 * @Date 2020/1/19 17:41
 */
@Aspect
@Component
public class RequestAspect {
    /**
     * 定義切入點,切入點為com.example.demo.aop.AopController中的所有函數
     * 通過 @Pointcut 注解聲明頻繁使用的切點表達式
     */
    @Pointcut(value = "execution(public * top.simba1949.controller.*.*(..))")
    public void aspectCenter(){
    }
    /**
     * 在連接配接點執行之前執行的通知
     */
    @Before(value = "aspectCenter()")
    public void before(){
        System.err.println("before");
    }
    /**
     * 在連接配接點執行之前執行的通知
     */
    @After(value = "aspectCenter()")
    public void after(){
        System.err.println("after");
    }
    /**
     * 在連接配接點執行之後執行的通知(傳回通知)
     */
    @AfterReturning("aspectCenter()")
    public void afterReturning(){
        System.err.println("afterReturning");
    }
    /**
     * 在連接配接點執行之後執行的通知(異常通知)
     */
    @AfterThrowing("aspectCenter()")
    public void afterThrowing(){
        System.err.println("afterThrowing");
    }
    /**
     * 環繞通知接受 ProceedingJoinPoint 作為參數,它來調用被通知的方法。
     * 通知方法中可以做任何的事情,當要将控制權交給被通知的方法時,需要調用ProceedingJoinPoint的proceed()方法。
     * 當你不調用proceed()方法時,将會阻塞被通知方法的通路。
     * @param pjp
     */
    @Around("aspectCenter()")
    public void around(ProceedingJoinPoint pjp) throws Throwable {
        System.err.println("around before");
        pjp.proceed();
        System.err.println("around after");
    }
}      

啟動類

package top.simba1949;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
/**
 * @Author Theodore
 * @Date 2020/1/19 15:44
 */
@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}      

配置檔案

server:
  port: 8082