一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第1天,点击查看活动详情。
Advisor接口的组成
Advisor接口通常由Advice接口和PonintCut接口组成。
- Advice:表示实际增强的逻辑入口
- Pointcut:表示哪些类、方法需要被拦截
AbstractAspectJAdvice
我们都知道advice(通知)有5种类型,最终通知、前置通知、后置通知、环绕通知、异常通知。
AbstractAspectJAdvice是通知类型:
- AspectJAfterReturningAdvice -- 最终通知
- AspectJMethodBeforeAdvice -- 前置通知
- AspectJAfterAdvice -- 后置通知
- AspectJAroundAdvice -- 环绕通知
- AspectJAfterThrowingAdvice -- 异常通知
根据上方的类图可以知道AbstractAspectJAdvice下面有5个实现类,但是只有三个类是实现了MethodInterceptor接口,可以直接转换为MethodInterceptor类(子类型可以转为父类型,例如Animal接口下,有Cat、Dog的子类实现。所以Cat、Dog可以转为Animal类)。
我们为什么要将AbstractAspectJAdvice的子类转换为MethodInterceptor呢?
因为在MethodInvocation的执行过程中,需要一个个的Advice(通知来增强),这里的通知就是MethodInterceptor。
也就是说MethodInterceptor接口有三个亲生的孩子:
- AspectJAfterAdvice -- 后置通知
- AspectJAroundAdvice -- 环绕通知
- AspectJAfterThrowingAdvice -- 异常通知
但是同样身为AbstractAspectJAdvice子类的AspectJAfterReturningAdvice 、AspectJMethodBeforeAdvice却不能转换为MethodInterceptor。
所以MethodInterceptor接口有两个私生子
- AfterReturningAdviceIntercepetor -- 最终通知
- MethodBeforeAdviceIntercepetor -- 前置通知
适配器模式
这里提供了适配器可以AspectJAfterReturningAdvice 、AspectJMethodBeforeAdvice转换为私生子。从而认祖归宗,转换为MethodInterceptor。
Advisor由Pointcut和Advice组成。
Adapter是通过适配器模式去完成Advice-->MethodInterceptor的适配过程。
来看其中的一个适配器的源码
class AfterReturningAdviceAdapter implements AdvisorAdapter, Serializable {
// 为什么传递过来的是Advisor对象?我们需要的不是MethodInterceptor吗?
// 因为根据类图可以发现,MethodInterceptor实现了Interceptor接口,Interceptor接口实现了Advice接口
// 而Advisor由Ponitcut和Advice组成,所以这里通过advisor.getAdvice()来获取advice对象。
// 并且强制转换为可以变成父类MethodInterceptor接口的子类。也就是AfterReturningAdviceInterceptor。
@Override
public MethodInterceptor getInterceptor(Advisor advisor) {
AfterReturningAdvice advice = (AfterReturningAdvice) advisor.getAdvice();
return new AfterReturningAdviceInterceptor(advice);
}
}