本文共 6466 字,大约阅读时间需要 21 分钟。
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中实现了此接口:ReflectiveMethodInvocationpublic 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 来实现切面)转载地址:http://dajxi.baihongyu.com/