Spring boot 使用Aop

  • AOP及自定義注解使用

  • Aop即為切面編程,通常以下幾個場景回使用到:

    • 事務

    • 攔截

    • 日志

    • 等等

  • 廢話不多說既然是Spring boot 那我們當然是使用Spring aop

使用方法

  • 先介紹一下AOP的常用注解
注解 解釋
@Pointcut 通常使用為@Pointcut("execution(* XXXXX.*.*(..))")可以匹配連接點,及定位要切入的地方在哪里。
@Before 增強處理,表示在切入點執(zhí)行前需要進行的操作或者需要執(zhí)行的方法
@After 表示在切入點執(zhí)行后,進行哪些操作
@AfterReturning pointcut/value:用于指定該切入點對應的切入表達式,returning:該屬性值指定一個形參名,用于表示Advuce方法中可以定義與此同名的形參,該形參可用于訪問目標方法的返回值
@AfterThrowing 同上,throwing,返回異常
@Around 增強相當于以上幾種總和,很強大但最好線程安全使用
@DeclareParents value:指向你要增強功能的目標對象,這里要增強UserServiceImpl對象,defaultImpl:引入增強功能的類,這里配置為UserValidatorImpl,用來提供校驗用戶是否為空的功能

開始實際使用

  • 注入pom
<dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-aop</artifactId>
 <version>2.2.2.RELEASE</version>
 </dependency>
  • 先寫切面類
@Component
@Aspect
public class Aoptest {
    @Pointcut("execution(* com.example.zj.contorller.*.*(..))")
    public void pc1(){}

    @Before(value = "pc1()")
    public void before(JoinPoint jp){
        String name = jp.getSignature().getName();
        System.out.println(name+"方法開始執(zhí)行");
    }

    @After(value = "pc1()")
    public void after(JoinPoint jp){
        String name = jp.getSignature().getName();
        System.out.println(name+"方法執(zhí)行結束");
    }

    @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());
    }

    @Around("pc1()")
    public Object around(ProceedingJoinPoint pjp)throws Throwable{
        System.out.println("方法環(huán)繞先");
        try {
            Object o =  pjp.proceed();
            System.out.println("方法環(huán)繞后,結果是 :" + o);
            return o;
        } catch (Throwable e) {
            e.printStackTrace();
            return null;
        }
    }
}
  • controller類
@RestController
public class test {
    @GetMapping("test1")
    public JsonResult test1(){
        return new JsonResult(200,"sucess","111");
    }


    @GetMapping("test2")
    public JsonResult test2(String name){
        if(name.length() < 3 || name.length() > 10)
        {
            throw new IllegalArgumentException("name參數(shù)的長度必須大于3,小于10!");
        }
        return new JsonResult(200,"sucess","222");
    }
}
  • 運行項目,請求controller中定義的url,結果為:
方法環(huán)繞先
test1方法開始執(zhí)行
方法環(huán)繞后,結果是 :JsonResult(code=200, msg=sucess, result=111)
test1方法執(zhí)行結束
test1方法返回值為JsonResult(code=200, msg=sucess, result=111)
  • 可以自行請求controller中定義的test2并拋出異常,觀察兩者執(zhí)行順序變化

  • 最后講一下代碼中的execution(* com.example.zj.contorller..*.*(..)):

    • 第一個*表示返回類型,*即為所有類型

    • 隨后跟著包名..及表示當前包及所有子包

    • 之后的*表示類名,*即所有類

    • 在之后的*即為方法

    • (..)表示方法參數(shù)..及表示任何參數(shù)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容