SpringBoot系列(1)——AOP-入門

BothSavage發表於2020-12-31

摘要

  • aop關鍵詞
  • spring aop小demo

概念

使用場景:與業務無關的且經常使用到的公共功能如鑑權,日誌,效能優化,事務,錯誤處理,資源池,同步,審計,冪等等

優點:降低耦合度,易擴充套件,高複用

實現方式:靜態代理(AspectJ) + 動態代理(CGlib/Jdk)

aop關鍵詞

  • 連線點(Joinpoint) 連線點就是增強的實現
  • **切點(PointCut)**就是那些需要應用切面的方法
  • 增強(Advice)
    • 前置通知(before)
    • 後置通知(after)
    • 異常通知(afterThrowing)
    • 返回通知(afterReturning)
    • 環繞通知(around)
  • 目標物件(Target)
  • **織入(Weaving)**新增到對目標類具體連線點上的過程。
  • 代理類(Proxy) 一個類被AOP織入增強後,就產生了一個代理類。
  • 切面(Aspect) 切面由切點和增強組成,它既包括了橫切邏輯的定義,也包括了連線點的定義
    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-msMrp9qH-1609345464379)(http://assets.processon.com/chart_image/5fec99ba7d9c0863d3ffd467.png)]

Spring aop測試

pom

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.3.5.RELEASE</version>
    <relativePath/>
</parent>

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

aspect

@Component
@Aspect 
public class DemoAspect {


    //切入點1:匹配xxx類下的方法名以demo開頭、引數型別為int的public方法
    @Pointcut("execution(public * com.bothsavage.service.DemoService.demo*(int))")
    public void matchCondition() {}

    //切入點2:匹配xxx類下的方法名以demo開頭、引數型別為long的public方法
    @Pointcut("execution(public * com.bothsavage.service.DemoService.demo1*(long))")
    public void matchCondition_() {}

    //前置
    @Before("matchCondition()")
    public void before() {
        System.out.println("Before");
    }

    //全域性後置
    @After("matchCondition()")
    public void after(){
        System.out.println("after");
    }

    //返回後置
    @AfterReturning("matchCondition()")
    public void afterReturning(){
        System.out.println("afterReturning");
    }

    //丟擲後置
    @AfterThrowing("matchCondition()")
    public void afterThrowing(){
        System.out.println("afterThrowing");
    }

    @Around("matchCondition_()")
    public Object around(ProceedingJoinPoint joinPoint) {
        Object result = null;
        System.out.println("before");
        try{
            result = joinPoint.proceed(joinPoint.getArgs());//獲取引數
            System.out.println("after");
        } catch (Throwable e) {
            System.out.println("after exception");
            e.printStackTrace();
        } finally {
            System.out.println("finally");
        }
        return result;
    }

}

service

@Service
public class DemoService {

    public void demo(int arg1){
        System.out.println(arg1);
    }

    public void demo1(long arg1){
        System.out.println(arg1);
    }
    
}

test

@SpringBootTest
public class DemoServiceTest {
    
    @Autowired
    DemoService demoService;

    //測試單獨四個
    @Test
    public void testDemo1(){
        demoService.demo(1);
    }
    
    //測試around
    @Test
    public void testDemo2(){
        demoService.demo1(1L);
    }
}

參考

[1].Spring AOP——簡單粗暴,小白教學

[2].CGLib動態代理

[3].關於 Spring AOP (AspectJ) 你該知曉的一切

[4].Spring AOP用法詳解

本文作者: Both Savage
本文連結: https://bothsavage.github.io/2020/12/28/SpringBoot/SpringBoot系列(1)——AOP-入門/
版權宣告: 本部落格所有文章除特別宣告外,均採用 BY-NC-SA 許可協議。轉載請註明出處!

相關文章