Spring | 類分析

Neking發表於2024-07-17

類分析: AspectJExpressionPointcut

AspectJExpressionPointcut 類實現了 PointcutClassFilterMethodMatcher 介面,主要用於透過 AspectJ 表示式定義切入點。在 AOP 中,這種方式允許我們使用複雜的表示式來匹配類和方法,從而實現更靈活的切面邏輯。

類宣告和欄位

public class AspectJExpressionPointcut implements Pointcut, ClassFilter, MethodMatcher {

    private static final Set<PointcutPrimitive> SUPPORTED_PRIMITIVES = new HashSet<PointcutPrimitive>();

    static {
        SUPPORTED_PRIMITIVES.add(PointcutPrimitive.EXECUTION);
    }

    private final PointcutExpression pointcutExpression;
  • SUPPORTED_PRIMITIVES:這是一個靜態集合,包含了該類支援的 AspectJ 切點原語。在這裡,支援的原語是 EXECUTION,表示方法執行。
  • pointcutExpression:這是解析後的切點表示式,用於匹配類和方法。

構造方法

public AspectJExpressionPointcut(String expression) {
PointcutParser pointcutParser = PointcutParser.getPointcutParserSupportingSpecifiedPrimitivesAndUsingSpecifiedClassLoaderForResolution(SUPPORTED_PRIMITIVES, this.getClass().getClassLoader());
pointcutExpression = pointcutParser.parsePointcutExpression(expression);
}
  • 構造方法接收一個 AspectJ 表示式字串。
  • PointcutParser 用於解析傳入的表示式,支援指定的切點原語,並使用當前類載入器進行解析。
  • 解析後的表示式儲存在 pointcutExpression 欄位中。

實現 ClassFilter 介面的方法

@Override
public boolean matches(Class<?> clazz) {
    return pointcutExpression.couldMatchJoinPointsInType(clazz);
}
  • 該方法用於判斷給定的類是否與切點表示式匹配。
  • pointcutExpression.couldMatchJoinPointsInType(clazz):返回一個布林值,表示該類中的連線點是否可能與表示式匹配。

實現 MethodMatcher 介面的方法

@Override
public boolean matches(Method method, Class<?> targetClass) {
    return pointcutExpression.matchesMethodExecution(method).alwaysMatches();
}
  • 該方法用於判斷給定的方法是否與切點表示式匹配。
  • pointcutExpression.matchesMethodExecution(method).alwaysMatches():返回一個布林值,表示方法執行是否與表示式匹配。

實現 Pointcut 介面的方法

@Override
public ClassFilter getClassFilter() {
    return this;
}

@Override
public MethodMatcher getMethodMatcher() {
    return this;
}
  • 這兩個方法返回當前物件,因為該類本身實現了 ClassFilter 和 MethodMatcher 介面。

整體流程

  1. 建立 AspectJExpressionPointcut 物件
    • 傳入 AspectJ 表示式字串,初始化 PointcutParser 並解析表示式,生成 pointcutExpression。
  2. 匹配類和方法
    • 使用 matches(Class<?> clazz) 方法匹配類。
    • 使用 matches(Method method, Class<?> targetClass) 方法匹配方法。
  3. 返回自身
    • getClassFilter() 和 getMethodMatcher() 方法返回自身,方便在 AOP 框架中使用。

示例應用

假設你要建立一個 AspectJExpressionPointcut 例項,用於匹配所有 com.example.service 包中名稱以 get 開頭的方法:

String expression = "execution(* com.example.service.*.get*(..))";
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(expression);

總結

AspectJExpressionPointcut 是一個強大的工具,允許我們使用複雜的 AspectJ 表示式來定義切入點,靈活地匹配類和方法。這種方式在大型專案中尤其有用,因為它提供了比簡單字串匹配更強的表達能力,支援更復雜的切面邏輯。

相關文章