在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

初学者刚接触AOP感觉很难接受,总感觉通知执行的顺序总是千遍万化,总是拿捏不定,原因是不知道它执行的一个原理,接下来笔者稍微详解一下AOP中通知事件的一个执行顺序。

想要搞懂通知执行顺序,首先得了解几个类,ReflectiveMethodInvocation,MethodInterceptor,这两个类在AOP中起到了很关键性的作用,不知道这两个类的同学可以私下去了解下,其实通知的执行就像是递归,当我们启动程序时,JdkDynamicAopProxy这个类中的invoke方法会帮我们获取到一个集合,这个集合里面放的就是我们通知的所有拦截器

// Get the interception chain for this method.

List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

然后将这个所有拦截器放到一个对象中,这个对象就是前面说的ReflectiveMethodInvocation,而这个对象的作用笔者认为它就是用于维护这些通知的一个执行顺序

// We need to create a method invocation...

MethodInvocation invocation =

new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);

// Proceed to the joinpoint through the interceptor chain.

retVal = invocation.proceed();

调用proceed()方法后,他们会不断递归调用,然后最终得到执行顺序,假如我得到的通知集合为如下图所示的顺序 结合代码进行分析,可以得到他们的执行顺序 代码:

@Override

@Nullable

public Object proceed() throws Throwable {

// We start with an index of -1 and increment early.

if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {

return invokeJoinpoint();

}

Object interceptorOrInterceptionAdvice =

this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);

if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {

// Evaluate dynamic method matcher here: static part will already have

// been evaluated and found to match.

InterceptorAndDynamicMethodMatcher dm =

(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;

Class targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());

if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {

return dm.interceptor.invoke(this);

}

else {

// Dynamic matching failed.

// Skip this interceptor and invoke the next in the chain.

return proceed();

}

}

else {

// It's an interceptor, so we just invoke it: The pointcut will have

// been evaluated statically before this object was constructed.

return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);

}

}

他们最终的执行顺序 从图中可以看出,这个就类似于递归,有点让人难以理解的是这个目标方法竟然是在最后执行,但是结合每个通知类中的invoke()方法仔细想想,这样的顺序十分合理,想要更进一步的理解,只有自己去DEBUG一遍才能领悟其中的思想。

对于集合中拦截器的顺序是如何排序的呢?其实底层采用的是拓扑排序的,所以这也就说明了为什么我们总是捉摸不透通知的执行顺序。

当我们了解了通知的执行原理后,那我们是否也可以自己写一个通知?

PS:如果这篇文章帮助到你,请双击点赞,谢谢!

精彩内容

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: 

发表评论

返回顶部暗黑模式