天天看點

程式員晉級之路——初識AOP

前言

何為AOP?AOP就是面向切面的程式設計。

何為面向切面的程式設計?就像高速公路的省界收費站一樣,每條進出我們省的高速都會在省界上設立一個收費站,那麼省界就是一個切面,收費站就是我們的處理方案,我們需要做的是定義省界這個面和在面上的收費站的功能。

應用場景

在項目完成之後,傳遞之前我們一般會對程式進行壓力測試,在測試中怎麼更加精準的定位系統運作的瓶頸呢?這時候你需要AOP監測每個接口甚至每個方法執行的時間!

在項目做異常處理時,我們怎樣才能更加簡單明了,将所有異常統一截取到同一個方法中進行處理?這時候你需要AOP将抛出的異常接受并處理!

AOP的定義非常靈活,可以是傳回值類型,也可以是注釋,也可以是某一個包下的所有方法或者指定方法,是以學習AOP之後,你不需要擔心沒有用武之地!

AOP結構

首先需要在這個類上添加一個@Aspect注釋,這就聲明了這個類是一個切面。

如下例子,将所有傳回值為指定類型的方法定義為一個切面:

@Aspect
@Component
@Slf4j
public class ResultAspect {
    // 切入點  所有傳回值類型是com.test.xbo包下ResultBO的方法
    @Pointcut("execution(public com.test.xbo.ResultBO *(..))")
    public void ResultAspect() {
    }
    // 環繞通知,參數必須為ProceedingJoinPoint,proceed就是被切面的方法
    @Around("ResultAspect()")
    public Object deAround(ProceedingJoinPoint joinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();
        joinPoint.proceed();
        String str = "## 控制器運作時間:" + joinPoint.getSignature() + ":" + (System.currentTimeMillis() - startTime);
        return null;
    }
}

      

再如,我定義一個注釋,将所有添加該注釋的方法定義為一個切面:

1、定義一個注釋,添加該注釋的方法會列印出該方法執行的時間:

@Target({ ElementType.METHOD, ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface DoneTime {
    String param() default "";
}      

2、定義一個切面

@Aspect
@Component
@Slf4j
public class DoneTimeAspect {
    @Around("@annotation(doneTime)")
    public Object around(ProceedingJoinPoint joinPoint, DoneTime doneTime) throws Throwable {
        long startTime = System.currentTimeMillis();
        Object o = joinPoint.proceed();
        String str = "## DoneTime-" + joinPoint.getSignature() + ":" + (System.currentTimeMillis() - startTime);
        log.error(str);
        return o;
    }
}

      

這樣我們就完成了兩個非常典型的AOP切面的例子!

繼續閱讀