我们拿集合里面的 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 支持字段、方法、构造函数等等 , 所以它更加强大 , 当然也更加复杂 。
- 套餐资费|广电放号 5G套餐竞争告别“三国时代”
- 英特尔|两倍变焦自拍能有多大区别?苹果、三星、OPPO自拍样张解析
- MacBook Pro|淘宝网企业和个人开店哪个费钱?差别大吗?
- 小米科技|小米两款“Ultra”新机齐遭曝光,分别搭载骁龙8+和天玑9000+芯片
- 百度地图|Java程序员应知应会之Maven和Gradle的区别
- |买手机别抠搜,4款目前口碑最好的旗舰手机,用个三五年不成问题
- iphone11|2022年最不值得买的三款手机,配置虽高但缺点明显,别花冤枉钱了
- 显卡|购机别犹豫,vivo S15系列满足你的用机需求,入手更划算
- 空调|空调移机“坑”巨多,这些套路一定要牢记,别让自己再花冤枉钱了
- Java|微信转账时弹出“这行字”,别输付款密码,有人已经中招了
