Pointcut 交集、聯集操作


如 果您建立了多個Pointcuts,並且在這中間,您發現到有幾個Pointcuts的定義可以組合在一起,成為另一個Pointcuts的定義,在 Spring中您可以直接對現在的Pointcuts物件,進行交集或(Intersection)、聯集(Union)的操作, org.springframework.aop.support.ComposablePointcut是Pointcut的實作類別,可以操作它的 intersection()、union()方法來完成這個操作:
ComposablePointcut intersection(ClassFilter filter);
ComposablePointcut intersection(MethodMatcher mm)
ComposablePointcut intersection(Pointcut other)
ComposablePointcut union(ClassFilter filter)
ComposablePointcut union(MethodMatcher mm)
         
例如:
Pointcut pc = new ComposablePointcut()
                     .union(classFilter)
                     .intersection(methodMatcher)
                     .intersection(pointcut);

在ComposablePointcut中沒有方法可以處理兩個Pointcut的聯集,您要使用org.springframework.aop.support.Pointcuts的union()方法,例如:
Pointcut union = Pointcuts.union(pointcut1, pointcut2);

當然的,這是必須在程式中直接撰寫才可以進行交集或聯集操作,如果您想要可以在Bean定義檔中直接宣告,則您可以設計一個類別,然後於Bean定義檔中宣告,這可以增加Pointcut操作後的重用性,例如:
package onlyfun.caterpillar;

import java.util.List;

import org.springframework.aop.ClassFilter;
import org.springframework.aop.MethodMatcher;
import org.springframework.aop.Pointcut;
import org.springframework.aop.
                        framework.AopConfigException;
import org.springframework.aop.support.Pointcuts;

public class UnionPoint implements Pointcut {
    private Pointcut pointcut;

    public ClassFilter getClassFilter() {
        return getPointcut().getClassFilter();
    }

    public MethodMatcher getMethodMatcher() {
        return getPointcut().getMethodMatcher();
    }

    public void setPointcuts(List pointcuts) {
        if(pointcuts == null || pointcuts.size == 0) {
            throw new AopConfigException(
                          "至少要設定一個Pointcut");
        }

        pointcut = (Pointcut) pointcuts.get(0);

        for(int i = 0; i < pointcuts.size(); i++) {
             Pointcut next = (Pointcut) pointcuts.get(i);
             pointcut = Pointcuts.union(pointcut, next);
        }
    }

    private Pointcut getPointcut() {
        if(pointcut == null) {
             throw new AopConfigExeption("沒有設定Pointcut");
        }
         return pointcut;
    }
}