SpringBoot中定位切點的兩種常用方法

有時候,我們使用AOP來進行放的增強,編寫切面類的時候,需要定位在哪個方法上試用該切面進行增強,本片文章主要講解兩種在SpringBoot中定位切點的方法,一種是使用execution表達式的方法,一種則是利用自定義註解的方法。

接下來以一個簡單的例子來講解這兩種方法的使用方式。

<==========方法執行前==========>
method();
<==========方法執行後==========>

execution 表達式

execution表達式的方式主要是在定義切點的時候,通過表達式的方式選取到所需要增強的方法。

execution表達式解讀

execution(<修飾符模式>?<返回類型模式><方法名模式>(<參數模式>)<異常模式>?)
類型 解讀 是否必須 示例
<修飾符模式> 表示所選的修飾符類型 public/private/…
<返回類型模式> 表示所選的返回值類型 void/int/…
<方法名模式> 表示所選的包或者方法 com.luke.service/com.luke.controller.*/…
(<參數模式>) 表示所選方法的參數 *(..)/*(String name)/*(int size, ..)/…
<異常模式> 表示所選方法的異常類型 throws Exception/…
 // 匹配指定包中的所有方法
execution(* com.luke.service.*(..))

// 匹配當前包中的所有public方法
execution(public * UserService.*(..))

// 匹配指定包中的所有public方法,並且返回值是int類型的方法
execution(public int com.luke.service.*(..))

// 匹配指定包中的所有public方法,並且第一個參數是String,返回值是int類型的方法
execution(public int com.luke.service.*(String name, ..))

自定義切面類:

@Aspect
@Component
public class LogAspect {

    @Pointcut("execution(* com.luke.springdata.controller.*.*(..))")
    public void operationLog(){}

    /**
     * 這裡隻定義一個Around的增強做展示
     */
    @Around("operationLog()")
    public Object doAround(ProceedingJoinPoint joinPoint) {
        Object proceed = null;
        try {
            System.out.println("方法執行前");
            proceed = joinPoint.proceed();
            System.out.println("方法執行後");
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return proceed;
    }
}

此切點的execution表達式為com.luke.springdata.controller包下的所有方法。
使用**@Around**註解表明增強的方法,並且指定切點。

測試用Controller類

@RestController
@RequestMapping("/person")
public class PersonController {

    @GetMapping("/test")
    public void test(){
        System.out.println("方法執行瞭");
    }
    
}

運行項目,調用該方法,查看結果。

方法執行前
方法執行瞭
方法執行後

自定義註解的方法

自定義註解的方式就是在需要增強的方法上面加上自定義的註解即可。

自定義註解類:

@Documented
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Log{
    
}

這裡自定義瞭一個註解Log,該註解隻能加在方法上。
自定義切面類:

@Aspect
@Component
public class LogAspect {

    @Pointcut("@annotation(com.luke.springdata.annotation.Log)")
    public void operationLog(){}

    /**
     * 這裡隻定義一個Around的增強做展示
     */
    @Around("operationLog()")
    public Object doAround(ProceedingJoinPoint joinPoint) {
        Object proceed = null;
        try {
            System.out.println("方法執行前");
            proceed = joinPoint.proceed();
            System.out.println("方法執行後");
        } catch (Throwable throwable) {
            throwable.printStackTrace();
        }
        return proceed;
    }
}

這裡編寫的自定義個切面類,用**@Pointcut註解定義一個切面,並且這次采用@annotation(xxx)**的方式表明如果哪個方法上添加瞭xxx註解,則就使用該切面做增強。

同時在每個增強的方法上使用該切面,隨後編寫正常的方法增強邏輯即可。

測試用Controller類

@RestController
@RequestMapping("/person")
public class PersonController {

    @Log
    @GetMapping("/test")
    public void test(){
        System.out.println("方法執行瞭");
    }
    
}

此時在需要使用切面的方法上加入**@Log**註解,調用該方法,查看效果。

方法執行前
方法執行瞭
方法執行後

總結

兩種方式均能實現AOP的功能,在使用上,如果某個包下面的所有方法,都需要這個切面進行增強,那麼使用execution表達式的方式更方便。但如果隻有部分方法需要,並且分佈在不同的類中,則註解的方式更靈活。

到此這篇關於SpringBoot中定位切點的兩種常用方法的文章就介紹到這瞭,更多相關SpringBoot 定位切點內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: