Springboot中AOP的使用

AOP是spring的兩個主要模塊功能之一,總結一下aop的基本用法

切面類組成

首先需要在類中用@Aspect,說明這個類時切面類,這個類主要由兩個部分組成:@PointcutAdvice

@Pointcut

@Pointcut是一個註解,標註在類中的方法上,主要的作用是說明要處理那些類和那些方法。

@Pointcut 裏的參數式一個表達式,包括指示器、通配符和運算符。

指示器按功能主要包括5類:

  • 匹配方法:execution()
  • 匹配註解:@target() @arges() @within() @annotation()
  • 匹配包或類型:within()
  • 匹配對象:this() bean() target()
  • 匹配參數:arges()

    注意!! 只有匹配註解的前邊有@符號

通配符主要包含3種:

  • *:任意數量的字符
  • +:指定類及其子類
  • ..:任意數的子包或參數

運算符也主要包括3種:

  • &&:與
  • ||:或
  • !:非

Advice

Advice說明了要執行的時機,主要是標註的類的方法上。

Advice主要有5種註解:

  • @Before:前置通知
  • @After: 後置通知,方法執行完之後
  • @AfterReturning: 返回通知,成功執行之後
  • @AfterThrowing:異常通知,拋出異常之後
  • @Around:環繞通知

用法

@Pointcut用法

在@Pointcut中execution()的應用最廣,所以主要以execution()爲例說明@Pointcut的用法
execution()的語法爲:
execution(方法修飾符(可選) 返回類型 方法名 參數 異常模式(可選))

java
@Pointcut("execution(public * com.example.aopdemo.Controller.*.*(..))")
public void excudeService(){}

這個java代碼中:
第一個* 號說明返回值爲任意類型
第二個*號說明是任意類
第三個* 號說明的是任意方法
.. 說明參數爲任意個
所以整個 @Pointcut說明處理的是com.example.aopdemo.Controller包下所有的類以及類中所有的方法,方法參數不限的方法。

Advice用法

Advice的用法大同小異,主要的差別是執行的時機,所以,主要以@Before爲例說明用法
“`java
@Before(“excudeService()”)
public void before(JoinPoint joinPoint){

    MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
    Method method=methodSignature.getMethod();
    logger.info("-----------"+method.getName());
    logger.info("---------before---------");
}

``
這個
before方法說明在excudeService()`這個@Pointcut處理的範圍之內,所有方法運行之前先運行before函數。

完整Aspect類例子的代碼


import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Aspect
@Component
public class AopConfig {

    Logger logger = LoggerFactory.getLogger(AopConfig.class);

    @Pointcut("execution(public * com.example.aopdemo.Controller.*.*(..))")
    public void excudeService(){}

    @Pointcut("execution(* *..find*(String)) && within(com.example..*) ")
    public void matchLongArg(){}


    @Before("excudeService()")
    public void before(JoinPoint joinPoint){

        MethodSignature methodSignature = (MethodSignature) joinPoint.getSignature();
        Method method=methodSignature.getMethod();
        logger.info("-----------"+method.getName());
        logger.info("---------before---------");
    }


    @After("excudeService()")
    public void after(JoinPoint joinPoint){


        Object [] args = joinPoint.getArgs();
        for (int i = 0; i < args.length; i++) {
            logger.info(String.valueOf(args[i]));
        }

        logger.info("---------after---------");
    }


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