前言
何為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切面的例子!