【源码】Spring AOP 5 Advisor
前言
Advisor 是 Spring AOP 对 Advice 和 Pointcut 的抽象,可以理解为“执行通知者”,一个 Pointcut (一般对应方法)和用于“增强”它的 Advice 共同组成这个方法的一个 Advisor
Advisor
public interface Advisor {
// 一个空的 Advice
Advice EMPTY_ADVICE = new Advice() {};
// 获取 Advice
Advice getAdvice();
boolean isPerInstance();
}
顶级接口,声明了获取 Advice 的方法
PointcutAdvisor
public interface PointcutAdvisor extends Advisor {
Pointcut getPointcut();
}
提供 Pointcut 的获取方法
AbstractPointcutAdvisor
public abstract class AbstractPointcutAdvisor implements PointcutAdvisor, Ordered, Serializable {
// ...
}
最通用的抽象,实现了 Ordered
接口,Advice
和 Pointcut
交给子类发挥
AbstractGenericPointcutAdvisor
public abstract class AbstractGenericPointcutAdvisor extends AbstractPointcutAdvisor {
private Advice advice = EMPTY_ADVICE;
public void setAdvice(Advice advice) {
this.advice = advice;
}
@Override
public Advice getAdvice() {
return this.advice;
}
}
通用抽象,暴露 setAdvice
方法,其子类可以专注于提供或者构造不同的 MethodMatcher
,比如:
RegexpMethodPointcutAdvisor
根据传入的patterns
构造JdkRegexpMethodPointcut
AspectJExpressionPointcutAdvisor
提供AspectJExpressionPointcut
来匹配传入的AspectJ
表达式NameMatchMethodPointcutAdvisor
提供NameMatchMethodPointcut
来匹配传入的mappedName
方法名,同时支持指定ClassFilter
AbstractBeanFactoryPointcutAdvisor
public abstract class AbstractBeanFactoryPointcutAdvisor extends AbstractPointcutAdvisor implements BeanFactoryAware {
@Nullable
private String adviceBeanName;
@Nullable
private BeanFactory beanFactory;
@Nullable
private transient volatile Advice advice;
// ...
@Override
public Advice getAdvice() {
// 缓存
Advice advice = this.advice;
if (advice != null) {
return advice;
}
// 如果是单例直接从 bean工厂 获取
if (this.beanFactory.isSingleton(this.adviceBeanName)) {
advice = this.beanFactory.getBean(this.adviceBeanName, Advice.class);
this.advice = advice;
return advice;
}
else {
// ...
}
}
// 略
}
- 基于提供的
adviceBeanName
从容器中获取Advice
- 子类提供具体的
Pointcut
,事务实现的BeanFactoryTransactionAttributeSourceAdvisor
、缓存实现的BeanFactoryCacheOperationSourceAdvisor
都是它的子类,在对应的文章会具体了解
StaticMethodMatcherPointcutAdvisor
public abstract class StaticMethodMatcherPointcutAdvisor extends StaticMethodMatcherPointcut
implements PointcutAdvisor, Ordered, Serializable {
private Advice advice = EMPTY_ADVICE;
// ...
// 构造方法接受一个 Advice
public StaticMethodMatcherPointcutAdvisor(Advice advice) {
Assert.notNull(advice, "Advice must not be null");
this.advice = advice;
}
// 接受一个 Advice
public void setAdvice(Advice advice) {
this.advice = advice;
}
// ...
// 本身就是一个 StaticMethodMatcherPointcut
@Override
public Pointcut getPointcut() {
return this;
}
}
在 AOP
的实现中已经不止一次见到这种接口组合实现的设计模式了:
MethodInterceptor
组合BeforeAdvice
的MethodBefreAdviceIntercpetor
,invoke
驱动整个拦截链的调用并组合BeforeAdvice
的通知逻辑StaticMethodMatcher
组合Pointcut
的StaticMethodMatcherPointcut
,借此获得ClassFilter
的能力,子类专注于实现match
逻辑StaticMethodMatcherPointcut
组合PointcutAdvisor
的StaticMethodMatcherPointcutAdvisor
,借此获取Advice
的能力,子类同样专注于实现match
逻辑,跟AbstractGenericPointcutAdvisor
类似,只是后者专注于提供一个具体的Pointcut
示例实现 demo
public class StaticMethodMatcherPointcutAdvisorDemo extends StaticMethodMatcherPointcutAdvisor {
// 实现 match 逻辑
@Override
public boolean matches(Method method, Class<?> targetClass) {
return true;
}
@Test
public void test() {
StaticMethodMatcherPointcutAdvisorDemo demo = new StaticMethodMatcherPointcutAdvisorDemo();
// 作为一个 Pointcut 可以暴露 ClassFilter 的能力
demo.setClassFilter(clazz -> true);
// 作为一个 PointcutAdvisor 可以暴露 Advice 的能力
demo.setAdvice(new MethodBeforeAdviceInterceptor((
(method, args, target) -> System.out.println("before"))));
// MethodMatcher 的能力
demo.matches(null, null);
}
}
总结
整体上,我认为可以理解成 Advisor = Pointcut + Advice
,聚焦于它的 Advisor#getAdvice
和 PointcutAdvisor#getPointut
的实现即可
上一篇:【源码】Spring AOP 4 Pointcut
下一篇:【源码】Spring AOP 6 AspectInstanceFactory
参考
【小家Spring】Spring AOP之Advisor、PointcutAdvisor、IntroductionAdvisor、IntroductionInterceptor(引介增强)