AOP联盟是java对于AOP提供的一系列标准接口,顶层接口有:
Advice通知,及其继承接口MethodInterceptor方法拦截器;
JointPoint连接点,及其继承接口MethodInvocation。
Spring或其他具有AOP概念的框架都会依赖于此,从Spring扩展的接口来看,对于AOP的支持局限于方法的拦截。
比如Spring AOP中就实现了Advice的扩展接口:方法前置增强、方法后置增强、异常增强等;
另外还有对这些Advice的包装实现:MethodInterceptor方法拦截器。
Spring中对于JoinPoint的实现包括了ProxyMethodInvocation,是AOP的核心类。
另外Spring新增了一个PointCut切点的概念,一个PointCut对应多个JointPoint。
在分析源码实现之前,先来看一些基本概念与核心接口。
AOP Alliance 是java中对于面向切面提供了一系列标准化接口,Spring或其他具有AOP概念的框架会依赖这个包。
这个包中有两个顶层接口:
Advice接口及其继承接口:
接口关系:
Advice
|
├── Interceptor
| |
| ├── MethodInterceptor
| ├── ConstructorInterceptor
接口方法:
(注意此处的MethodInterceptor是org.aopalliance.intercept.MethodInterceptor而非cglib包中的同名接口)
public interface Advice {
}
public interface Interceptor extends Advice {
}
//Spring中实现了此接口:MethodBeforeAdviceInterceptor、AfterReturningAdviceInterceptor等
public interface MethodInterceptor extends Interceptor {
//需要执行的时候,调用invocation.proceed()
Object invoke(MethodInvocation invocation) throws Throwable;
}
public interface ConstructorInterceptor extends Interceptor {
Object construct(ConstructorInvocation invocation) throws Throwable;
}
Joinpoint接口及其继承接口:
Joinpoint
|
├── Invocation
| |
| ├── MethodInvocation
| ├── ConstructorInvocation
接口方法:
(注意此处的Joinpoint是org.aopalliance.intercept.Joinpoint,而非指Spring中的org.aspectj.lang.JoinPoint)
public interface Joinpoint {
// 执行此拦截点,并进入到下一个连接点
Object proceed() throws Throwable;
// 返回保存当前连接点静态部分的对象
Object getThis();
// 返回此静态连接点 一般就为当前的Method
AccessibleObject getStaticPart();
}
public interface Invocation extends Joinpoint {
// 获得参数,如方法入参
Object[] getArguments();
}
//作为AOP Alliance中的底层接口,Spring AOP中实现了此接口:ReflectiveMethodInvocation
public interface MethodInvocation extends Invocation {
// 返回当前被调用的Method
Method getMethod();
}
public interface ConstructorInvocation extends Invocation {
Constructor<?> getConstructor();
}
Spring AOP并不是自立门户,而是在AOP联盟定义的一系列接口上,提供实现类或者进行封装。
Spring对于Advice接口继承扩展:
Advice
|
├── Interceptor
| |
| ├── MethodInterceptor
| ├── ConstructorInterceptor
|
├── BeforeAdvice
| |
| ├── MethodBeforeAdvice
|
├── AfterAdvice
| |
| ├── ThrowsAdvice
| ├── AfterReturningAdvice
各个接口中方法:
public interface BeforeAdvice extends Advice {
}
public interface MethodBeforeAdvice extends BeforeAdvice {
void before(Method method, Object[] args, Object target) throws Throwable;
}
public interface AfterAdvice extends Advice {
}
public interface ThrowsAdvice extends AfterAdvice {
}
public interface AfterReturningAdvice extends AfterAdvice {
void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable;
}
Spring中对于Advice接口继承扩展:
Advice
|
├── Interceptor
| |
| ├── MethodInterceptor
| | |
| | ├── IntroductionInterceptor
| | ├── MethodBeforeAdviceInterceptor
| | ├── AfterReturningAdviceInterceptor
| | ├── ThrowsAdviceInterceptor
| ├── ConstructorInterceptor
|
├── BeforeAdvice
| |
| ├── MethodBeforeAdvice
|
├── AfterAdvice
| |
| ├── ThrowsAdvice
| ├── AfterReturningAdvice
接口方法,以MethodBeforeAdviceInterceptor为例:
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable {
private MethodBeforeAdvice advice;
// MethodBeforeAdviceInterceptor只是将MethodBeforeAdvice进行了一个包装
public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
Assert.notNull(advice, "Advice must not be null");
this.advice = advice;
}
@Override
public Object invoke(MethodInvocation mi) throws Throwable {
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );
return mi.proceed();
}
}
同样的,AfterReturningAdviceInterceptor是对AfterReturningAdvice的包装、ThrowsAdviceInterceptor是对ThrowsAdvice的包装。
Spring对于Joinpoint接口的继承扩展:
Joinpoint
|
├── Invocation
| |
| ├── MethodInvocation
| | |
| | ├── ProxyMethodInvocation
| | | |
| | | ├── ReflectiveMethodInvocation
| ├── ConstructorInvocation
接口方法:
public interface ProxyMethodInvocation extends MethodInvocation {
Object getProxy();
MethodInvocation invocableClone();
MethodInvocation invocableClone(Object... arguments);
void setArguments(Object... arguments);
void setUserAttribute(String key, Object value);
Object getUserAttribute(String key);
}
Pointcut是Spring AOP新增的接口,定义了Joinpoint连接点的匹配规则,即:一个Pointcut对应多个Joinpoint,也就是 Advice逻辑织入的Joinpoint连接点的集合
接口定义如下
public interface Pointcut {
ClassFilter getClassFilter();
MethodMatcher getMethodMatcher();
Pointcut TRUE = TruePointcut.INSTANCE;
}
Spring AOP新增了一个接口Advisor,用来包装 Advice通知 和 Pointcut切点 两个对象。
Advisor
|
├── PointcutAdvisor
├── IntroductionAdvisor
接口方法:
public interface Advisor {
Advice getAdvice();
boolean isPerInstance();
}
public interface PointcutAdvisor extends Advisor {
Pointcut getPointcut();
}
public interface IntroductionAdvisor extends Advisor, IntroductionInfo {
ClassFilter getClassFilter();
void validateInterfaces() throws IllegalArgumentException;
}
从Spring中所扩展的接口或者实现类来看,Spring 对 AOP 的支持局限于 方法的拦截。
(如果需求超过了简单的方法调用,如构造器或属性拦截,那么需要考虑使用 AspectJ 来实现切面)