随笔 - 303  文章 - 0  评论 - 3  阅读 - 15万

Spring核心思想之 AOP:AOP如何影响DI并引入三级缓存解决DI中涉及代理的问题

  Spring中AOP的实现与在Spring核心思想之 AOP:在自定义容器基础上实现AOP功能中实现的自定义AOP一样,采用后置处理器方式。在Spring的核心思想之DI:详解Spring DI循环依赖实现机制文中末尾提到了一个问题,为什么是三级缓存而不是二级。

  下面示例AOP是如何影响DI的?

          

  AService和BService依赖注入,如果A没有后置处理器相关操作,AService和BService如上图就完成了bean生成。然而如果存在后置处理器呢?类似于下图:

            

  BService注入AService后,系统就会自动提供一个名为 AsyncAnnotationBeanPostProcessor 的处理器,在这个处理器中会生成一个代理的 AService 对象,并用这个对象代替原本的 AService。关键在于:原本的 AService 和新生成的代理的 AService 是两个不同的对象,占两块不同的内存地址!

  此时就产生了一个问题:BService中注入的AService与最终的AService不一致!!!下面就是Spring提供的三级缓存的方案:

            

  创建一个 AService 的时候,通过反射刚把原始的 AService 创建出来之后,先去判断当前一级缓存中是否存在当前 Bean,如果不存在,则:

    •   首先向三级缓存中添加一条记录,记录的 key 就是当前 Bean 的 beanName,value 则是一个 Lambda 表达式 ObjectFactory,通过执行这个 Lambda 可以给当前 AService 生成代理对象。

    •   然后如果二级缓存中存在当前 AService Bean,则移除掉。

  现在继续去给 AService 各个属性赋值,结果发现 AService 需要 BService,然后就去创建 BService,创建 BService 的时候,发现 BService 又需要用到 AService。于是就先去一级缓存中查找是否有 AService,如果有,就使用;如果没有,则去二级缓存中查找是否有 AService,如果有,就使用;如果没有,则去三级缓存中找出来那个 ObjectFactory,然后执行这里的 get("AService")方法。关键操作就在这个方法中:

    在执行的过程中,会去判断是否需要生成一个代理对象,如果需要就生成代理对象返回,如果不需要生成代理对象,则将原始对象返回即可。最后,把拿到手的对象存入到AService二级缓存中以备下次使用,同时删除掉三级缓存中对应的数据。这样 BService 所依赖的AService  就创建好了(不管是原始的还是代理对象都在二级缓存中了)。

  接下来继续去完善 AService,去执行各种后置的处理器,此时,有的后置处理器想给 AService 生成代理对象,发现 AService 已经是代理对象了,就不用生成了,直接用已有的代理对象去代替 AService 即可。

  所以得出之前文章中的结论:三级缓存的使用将AOP提前操作了。

posted on   池塘里洗澡的鸭子  阅读(34)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示