Spring AOP的實現:三個基本屬性類的實現和解析
在深入瞭解AOP的實現原理之前,我們需要先了解一下關於AOP的三個基本的屬性類。PointCut切點, Advice通知, Advistor通知器。
Advice通知
首先來看一下Advice通知以及它的作用
Advice,定義了在連線點對連線點進行怎樣的增強操作。通過這個介面,對AOP的切面的增強進行進一步的劃分。比如
BeforeAdvice , AfterAdvice, ThrowsAdvice這些具體的增強類。
比如在BeforeAdvice類中定義了一個增強介面MethodBeforeAdvice,通過對其中的before()方法的實現實現對連線點也就是目標方法的前置增強。
public interface MethodBeforeAdvice extends BeforeAdvice {
void before(Method method, Object[] args, Object target) throws Throwable;
}
Pointcut切點
Pointcut(切點)決定了Advice通知應該作用於哪個連線點,也就是說通過Pointcut來定義需要增強的集合。這些集合的選取是按照一定的規則來完成的,對於這個規則的分析則是交由PointCut切點來完成。例如,這些需要增強的地方可以由某個正則表示式來進行標識或者根據某個方法名進行標識。
比如我們可以進入到org.springframework.aop.support.JdkRegexpMethodPointcut中來檢視一下這個切點是怎麼解析並最後持有解析到的方法的。
從Pointcut()的介面定義中我們可以發現,這個介面需要一個MethodMatcher(方法匹配器)來判斷是否對方法進行增強或者是否需要對方法進行Advice通知的配置。
我們來看一下org.springframework.aop.support.JdkRegexpMethodPointcut的父類。
org.springframework.aop.support.StaticMethodMatcherPointcut。這個類中實現了MethodMatcher,或者說這個類繼承了一個
org.springframework.aop.support.StaticMethodMatcher。也就是說這個類本身也是一個方法匹配器,
@Override
public final MethodMatcher getMethodMatcher() {
return this;
}
回到org.springframework.aop.support.JdkRegexpMethodPointcut中,可以通過這個類的matches方法進行正則表示式的匹配
@Override
protected boolean matches(String pattern, int patternIndex) {
Matcher matcher = this.compiledPatterns[patternIndex].matcher(pattern);
return matcher.matches();
}
public boolean matches() {
return match(from, ENDANCHOR);
}
Advistor通知器
完成對Advice和Pointcut的配置之後,需要一個物件把它們結合起來,完成這個功能的就是Advistor。通過Advistor,把Advice和Pointcut結合起來,可以定義在哪一個連線點實現怎樣的增強。
DefaultPointcutAdvisor 的實現程式碼如下。
public class DefaultPointcutAdvisor extends AbstractGenericPointcutAdvisor implements Serializable {
private Pointcut pointcut = Pointcut.TRUE;
public DefaultPointcutAdvisor() {
}
public DefaultPointcutAdvisor(Advice advice) {
this(Pointcut.TRUE, advice);
}
public DefaultPointcutAdvisor(Pointcut pointcut, Advice advice) {
this.pointcut = pointcut;
setAdvice(advice);
}
public void setPointcut(Pointcut pointcut) {
this.pointcut = (pointcut != null ? pointcut : Pointcut.TRUE);
}
@Override
public Pointcut getPointcut() {
return this.pointcut;
}
@Override
public String toString() {
return getClass().getName() + ": pointcut [" + getPointcut() + "]; advice [" + getAdvice() + "]";
}
}
在實現的程式碼中,我們可以看到Pointcut的單例模式
Pointcut TRUE = TruePointcut.INSTANCE;
這實際上是TruePointcut的一個例項物件。在它的實現中,我們可以看到
public MethodMatcher getMethodMatcher() {
return MethodMatcher.TRUE;
}
返回的是
MethodMatcher TRUE = TrueMethodMatcher.INSTANCE;
當然在我看來這只是一個舉例。實際上我們用到的更多的是關於正則表示式以及方法名匹配的Advistor
這三個類將貫穿之後對於AOP原理解析的始終,所以這三個類的作用的理解是很必要的。