我们拿集合里面的 MethodBeforeAdviceInterceptor 来举例看下 , 这个是目标方法执行的前置拦截 , 我们看下它的 invoke 实现 , 有更直观的认识:
invoke 的实现是先执行切入的前置逻辑 , 然后再继续调用 CglibMethodInvocation#proceed(也就是mi.proceed) , 进行下一个 interceptor 的调用 。
总结下 :
Spring 根据 @Before、@After、@AfterReturning、@AfterThrowing 这些注解 。
往集合里面加入对应的 Spring 提供的 MethodInterceptor 实现 。
比如上面的 MethodBeforeAdviceInterceptor, 如果你没用 @Before , 集合里就没有 MethodBeforeAdviceInterceptor。
然后通过一个对象 CglibMethodInvocation 将这个集合封装起来 , 紧接着调用这个对象的 proceed 方法 。
具体是利用 currentInterceptorIndex 下标 , 利用递归顺序地执行集合里面的 MethodInterceptor, 这样就完成了拦截链的调用 。
我截个调用链的堆栈截图 , 可以很直观地看到调用的顺序(从下往上看):
是吧 , 是按照顺序一个一个往后执行 , 然后再一个一个返回 , 就是递归呗 。
然后我再解释下上面的 chain 集合我们看到第一个索引位置的 ExposeInvocationInterceptor。
这个 Interceptor 作为第一个被调用 , 实际上就是将创建的 CglibMethodInvocation 这个对象存入 threadlocal 中 , 方便后面 Interceptor 调用的时候能得到这个对象 , 进行一些调用 。
从名字就能看出 expose:暴露 。
ok , 更多细节还是得自己看源码的 , 应付面试了解到这个程度差不多的 , 上面几个关键点一抛 , 这个题绝对稳了!
Spring AOP 和 AspectJ 有什么区别从上面的题目我们已经知道 , 两者分别是动态代理和静态代理的区别 。
Spring AOP 是动态代理 , AspectJ 是静态代理 。
从一个是运行时织入 , 一个在编译时织入 , 我们稍微一想到就能知道 , 编译时就准备完毕 , 那么在调用时候没有额外的织入开销 , 性能更好些 。
【spring|别再说 Spring AOP 默认用的是 JDK 动态代理】且 AspectJ 提供完整的 AOP 解决方案 , 像 Spring AOP 只支持方法级别的织入 , 而 AspectJ 支持字段、方法、构造函数等等 , 所以它更加强大 , 当然也更加复杂 。
- 裁员|阿里腾讯被爆裁员20%最直接反映了实体经济与互联网产业的区别!
- |线上店铺自运营与代运营的区别
- ai|1秒识别200个假大牌,清华阿里邀全国人才用20张图锻造“打假AI”
- 阿里巴巴|Java和JavaScript之间的区别
- exynos|别被数字骗了!三星新一代处理器Exynos 1280性能堪忧!
- 装机更轻松、灯效更智能!蓝宝石Radeon RX 6900 XT 16G D6超白金极光特别版显卡深度评测
- ota|iOS15.4真的耗电吗?可能你更新方法不对,聊聊OTA和线刷的区别
- 裁员|互联网大厂大规模裁员,别抱怨,毕业式裁员是给打工人最后的体面
- 索尼|索尼Sony电视型号详解,X系列和A系列区别很大,你选对了吗?
- 显卡|装一台(伪)小钢炮主机,测测win10和win11的区别大不大