Spring是根據類別名稱與方法名稱來定義Pointcut,當呼叫的類別與方法名稱符合Pointcut的定義時,將Advice縫合至應用程式上以提供服務。
Spring的Pointcut是透過實作org.springframework.aop.Pointcut介面來實現,其定義如下:
package org.springframework.aop;
public interface Pointcut {
ClassFilter getClassFilter();
MethodMatcher getMethodMatcher();
Pointcut TRUE = TruePointcut.INSTANCE;
}
public interface Pointcut {
ClassFilter getClassFilter();
MethodMatcher getMethodMatcher();
Pointcut TRUE = TruePointcut.INSTANCE;
}
Pointcut.TRUE是Pointcut介面的簡單實作,它傳回的ClassFilter是ClassFilter.TRUE,而傳回的MethodMatcher是傳回MethodMatcher.TRUE。
ClassFilter介面決定了一個類別是否要應用Advice,其定義如下所示:
package org.springframework.aop;
public interface ClassFilter {
boolean matches(Class clazz);
ClassFilter TRUE = TrueClassFilter.INSTANCE;
}
public interface ClassFilter {
boolean matches(Class clazz);
ClassFilter TRUE = TrueClassFilter.INSTANCE;
}
matches()方法中要決定傳入的類別是不是符合Pointcut的定義,ClassFilter.TRUE是ClassFilter介面的簡單實 作,它的matches()方法總是傳回true,如果您想要建立的Pointcut只考慮到方法名稱,則可以使用這個方法。
而MethodMatcher決定了某個方法是否要應用Advice,其定義如下所示:
package org.springframework.aop;
import java.lang.reflect.Method;
public interface MethodMatcher {
boolean matches(Method method, Class targetClass);
boolean isRuntime();
boolean matches(Method method,
Class targetClass, Object[] args);
MethodMatcher TRUE = TrueMethodMatcher.INSTANCE;
}
import java.lang.reflect.Method;
public interface MethodMatcher {
boolean matches(Method method, Class targetClass);
boolean isRuntime();
boolean matches(Method method,
Class targetClass, Object[] args);
MethodMatcher TRUE = TrueMethodMatcher.INSTANCE;
}
matches()方法決定了某個類別的某個方法是否符合Pointcut定義,有兩個版本,第一個版本使用於靜態Pointcut,像是 NameMatchMethodPointcutAdvisor 、 RegExpMethodPointcutAdvisor,第一個方法總是會被執行,如果是靜態Pointcut,則isRuntime()會傳回 false,此時第二個matches()方法不會被執行,只有在isRuntime()為true時,第二個版本的matches()才會被執行,例如 ControlFlowPointcut 。
MethodMatcher.TRUE是MethodMatcher的簡單實作,它的第一個版本的matches()總是傳回true, isRuntime()總是傳回false,表示靜態Pointcut,所以您不可以呼叫第二個版本的matches()方法,否則就會丟出 UnsupportedOperationException 例外。