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原理解析的始终,所以这三个类的作用的理解是很必要的。