随笔分类
Around与 其它通知之间的区别?
Around区别于其他的通知,可以认为,除了 Around之外的其它通知都是被动去执行的,而 Around不同,其是需要我们主动去执行的 (结合 ProceedingJoinpoint),若是不显式去调用目标代码的话,那么之后的通知以及对应的目标方法也不会被执行,这也是区别于其它 Advice的地方
为什么 Spring Aop不需要去设计 Around Advice?
从 AspectJ @Around执行上来讲,其是需要和 ProceedingJoinPoint配合执行被代理方法的,而 ProceedingJoinPoint其实是类似于 Java Method #invoke(Object,Object)的,即对应的便是去执行相应的方法
Spring Aop底层 ProxyFactory可以通过 addAdvice()与 Advice实现关联,而我们在实际编码时实际上就是去添加对应的实现 MethodInterceptor;Interceptor是对 Advice的扩展,MethodInterceptor是对 Interceptor的扩展,so,MethodInterceptor实际上也是对 Advice的扩展
而 MethodInterceptor中对应 invoke方法参数 MethodInvocation是我们拦截器链得以持续传播执行的关键,其和 ProceedingJoinPoint有点相似
而通过之前源码以及 Aop发展可知,Spring Aop最佳实践便是基于 MethodInvocation驱动的责任链模式,对应方法即为 proceed(),而基于 @Around的传播实践可知,对应 ProceedingJoinPoint #proceed()底层实现还是去调用了 MethodInvacation.proceed()
因此,便无需再为 Around单独去开辟一个 AroundAdvice或者 AroundAdviceMethodInterceptor的存在,因为其 ProceedingJoinPoint便能够实现 "行为调用"的主动,这也是笔者认为这也是与其它通知 Advice的一个关键区别吧
当存在多个相同定义的通知时,如何来保证这些定义之间的有序性?
当存在多个 Aspect时,并且存在多个 Advice定义在同一个 Joinpoint时,此时它们的执行顺序是怎样的?
或者说是,如何来让某一个 Advice优先执行?其实,针对这种问题,我们一般会先去考虑有没有 "排序"之类的执行实现
正如我们所想,Spring官方文档中也去显式说明了,针对这种情况,可以对 Aspect进行排序,即对应两种方法,一种是添加注解 @Order,而另一种则是去实现 Ordered接口,然,这两种接口对应实现其实恰好是相反的
对于前者,优先级默认是最低的 (对应整数最大值),而后者我们可以显式在 getOrder()中设置其优先级
不过这里需注意一点,由于 Aop在实现时默认添加了一个 ExposeInvocationInterceptor在拦截器 chain头,并且要求其要被最先执行,其对应的优先级为 Integer.MIN_VALUE,因此我们所设定的优先级必须要大于此值
并且,有这我们其实也可以看出,Around与 Before之间并没有绝对的执行顺序,只是针对于一个 Aspect中的 Around会优先执行于 Before,而不同 Aspect之间就不一定了,这里稍微注意一些
这块详细可以去看看之前 Aop源码解读中具体实现
怎么来理解自动动态代理?
自动动态代理,关键在于 Spring Aop和 Spring IoC是如何来进行整合的一个问题;
确切地来说,是 Aop代理对象是如何被 Spring IoC所识别并且进行运用的,通过自动动态代理,便实现了通过 IOC容器去整合 Target Bean、Advice Bean、Pointcut bean,这确实是简化了我们的开发过程,即打通了 Spring IoC与 AspectJ
对应的一些实现:BeanNameAutoProxyCreator、DefaultAutoProxyCreator、AnnotationAspectJAwareAutoProxyCreator