当前位置: 首页 > news >正文

开发施工建设网站审核建网站联系电话

开发施工建设网站审核,建网站联系电话,网站建设准备工作总结,网页制作与网站建设教程视频教程人人都能看懂的Spring源码解析#xff0c;Spring如何解决循环依赖原理解析什么是循环依赖循环依赖会有什么问题#xff1f;如何解决循环依赖问题的根本原因如何解决为什么需要三级缓存#xff1f;Spring的三级缓存源码走读Spring的三级缓存提前暴露getSingleton方法总结往期… 人人都能看懂的Spring源码解析Spring如何解决循环依赖原理解析什么是循环依赖循环依赖会有什么问题如何解决循环依赖问题的根本原因如何解决为什么需要三级缓存Spring的三级缓存源码走读Spring的三级缓存提前暴露getSingleton方法总结往期内容 人人都能看懂的Spring底层原理看完绝对不会懵逼简单易懂的Spring扩展点详细解析看不懂你来打我人人都能看懂的Spring源码解析配置解析与BeanDefinition加载注册简单易懂又非常牛逼的Spring源码解析ConfigurationClassPostProcessor的具体逻辑简单易懂值得收藏的Spring源码解析依赖注入和bean的初始化 原理解析 什么是循环依赖 两个BeanBeanA和BeanB它们都有一个引用指向对方这就是最简单的循环依赖。还有更复杂的循环依赖涉及到多个bean只要其中形成环就是循环依赖。 循环依赖会有什么问题 如果Spring不对这种情况做处理那么在进行依赖注入的时候就会出现死循环。 如何解决循环依赖 问题的根本原因 要解决循环依赖的问题首先就要分析导致这个问题的根本原因。 因为上面是假设Spring只有一个缓存那就是单例缓存池而且该缓存池是用于存放已初始化完成的bean而没有完成依赖注入的bean不算是初始化完成的bean所以不会放入单例缓存池中。 所以beanA依赖beanB时只能实例化一个beanB然后对其进行依赖注入而beanB又依赖了beanA所以又只能实例化一个beanA对其进行依赖注入这样就没完没了了。 如何解决 解决办法就是多增加一个缓存二级缓存用于存放已经实例化但是未完成初始化的bean。因为增加了一个二级缓存在bean被实例化的之后就预先放入到该二级缓存中那么在后续其他bean进行依赖注入的时候发现依赖了该bean然后检查到二级缓存中有就不需要往下进行实例化。 比如上图在第二次getBean(beanA)的时候二级缓存中已经存放了beanA因此不会往下再次进行beanA的实例化而是直接从缓存中取死循环因此就解决了。 为什么需要三级缓存 那看起来搞两级缓存就能解决问题但是Spring实际上是有三级缓存的那为什么Spring需要搞三级缓存呢 那是因为Spring要处理AOP我们可以想一想如果只有两级缓存要怎么同时处理循环依赖和AOP呢 此时就要在每个bean实例化后放入二级缓存之前都要判断一下这个bean是否需要进行AOP处理如果需要就要先通过动态代理生成代理对象放入二级缓存的就是代理对象如果不需要进行AOP处理那么就把原始对象放入二级缓存。 这个显然不符合Spring的设计。Spring的设计是把AOP放到依赖注入完成以后在初始化阶段触发的而现在却要把AOP的处理提前到实例化之后。 那如果还是要把AOP放到初始化阶段触发只有涉及到循环依赖的bean才提前进行AOP呢那就要在每次从二级缓存获取bean的时候都要判断一下是否需要进行AOP处理这样就太繁琐了。 因此最好的解决办法就是再加一级缓存三级缓存。先从二级缓存中取如果有直接返回如果二级缓存没有再从三级缓存中拿放入二级缓存并从三级缓存删除并且只有从三级缓存中取的时候才判断是否需要进行AOP处理。 Spring的三级缓存 singletonObjects一级缓存MapString, Object类型key是beanNamevalue是已初始化完成的bean。earlySingletonObjects二级缓存MapString, Object类型key是beanNamevalue是已实例化完成但是未进行初始化的bean。singletonFactories三级缓存MapString, ObjectFactory?key是beanNamevalue是ObjectFactory?类型。ObjectFactory是一个函数式接口可以视为一个回调函数里面的逻辑就是调用bean后置处理判断是否需要进行AOP处理如果需要则进行AOP处理返回一个代理对象如果不需要进行AOP处理则返回原始对象。 源码走读 Spring的三级缓存 上面描述的三级缓存就是DefaultSingletonBeanRegistry的成员变量。 而DefaultSingletonBeanRegistry又是DefaultListableBeanFactory的祖先类所以三级缓存就在DefaultListableBeanFactory里面。 提前暴露 AbstractAutowireCapableBeanFactory#doCreateBean方法首先调用createBeanInstance方法进行bean的实例化。 实例化以后就是判断是否需要提前暴露earlySingletonExposure为true如果需要则调用addSingletonFactory方法进行提前暴露。 然后下面的populateBean方法里面就是依赖注入的处理initializeBean方法里面就是bean初始化的处理这两个方法在前面的文章已经讲过。 需要提前暴露的条件 mbd.isSingleton()是否单例。this.allowCircularReferences是否允许循环依赖默认为true但是高版本改成默认为false了Spring希望我们把代码写的更好而不是指望Spring来给我们处理循环依赖的问题。isSingletonCurrentlyInCreation(beanName)该bean是否正在创建中。 三个条件都满足就调用addSingletonFactory方法提前暴露。 addSingletonFactory方法里面就是把beanName和ObjectFactory类型的对象singletonFactory放入三级缓存singletonFactories。这里的singletonFactory的就是外面的lambda表达式 () - getEarlyBeanReference(beanName, mbd, bean)。ObjectFactory是一个函数式接口里面有一个getObject方法而singletonFactory的getObject方法就是调用getEarlyBeanReference(beanName, mbd, bean)。 getSingleton方法 一个bean在依赖注入阶段要处理对别的bean的依赖会调用beanFactory的getBean方法尝试从容器中取getBean方法会先调用getSingleton方法尝试从三级缓存中取。 首先从第一级缓存取this.singletonObjects.get(beanName)不是null就返回如果第一级缓存取到的是null则从第二级缓存取this.earlySingletonObjects.get(beanName)不是null就返回如果第二级缓存取到的还是null则从第三级缓存取this.singletonFactories.get(beanName)如果第三级缓存取到的不是null则调用getObject方法获取getObject方法返回的对象放入二级缓存从三级缓存中删除如果第三级缓存取到的还是null就要走创建bean的逻辑 这里的singletonFactory的getObject实现方法就是addSingletonFactory方法的第二个参数的lambda表达式 () - getEarlyBeanReference(beanName, mbd, bean)也就是会调用 getEarlyBeanReference(beanName, mbd, bean) 方法获取返回的对象。 可以看到遍历所有的bean后置处理器判断如果是SmartInstantiationAwareBeanPostProcessor类型就回调getEarlyBeanReference方法这里会进入到AbstractAutoProxyCreator#getEarlyBeanReference方法。 wrapIfNecessary方法就是判断如果当前bean需要进行AOP处理则进行动态代理返回代理对象如果不需要进行AOP处理会返回原始对象。 总结 以上就是关于“Spring如何处理循环依赖”的讲解的全部内容。下面做一个简单总结 Spring是通过三级缓存解决循环依赖的。一级缓存是singletonObjects二级缓存是earlySingletonObjects三级缓存是singletonFactories。一个bean在实例化完成后在进行依赖注入之前如果判断满足三个条件当前bean是一个单例bean并且允许循环依赖并且当前bean正在创建中就会进行提前暴露放入到第三级缓存中。在依赖注入阶段会调用beanFactory的getBean方法获取依赖的beangetBean方法会先调用getSingleton方法尝试从三级缓存中取。getSingleton方法先尝试从第一级缓存取如果没有再从第二级缓存取如果再没有就从第三级缓存取如果第三级缓存中有会调用getObject方法获取返回对象再放入第二级缓存从第三级缓存中删除。singletonFactory的getObject方法会调用getEarlyBeanReference方法里面会调用到AbstractAutoProxyCreator的getEarlyBeanReference方法判断是否要进行AOP处理如果需要会进行动态代理返回代理对象如果不需要就返回原始对象。
http://www.hkea.cn/news/14368400/

相关文章:

  • 牡丹江城乡建设局网站买卖域名的网站
  • 长春网站建设联系吉网传媒优wordpress文档模板下载
  • 别的网站做相关链接怎么做温州做网站建设哪家好
  • 网站推广昔年下拉免费域名申请网站
  • 增城网站建设沧浪企业建设网站方法
  • 网站建设 中企动力ui界面设计公司
  • 订房网站开发科技之星
  • 设计单位在厦门什么网站做的网站怎么上传图片
  • 柳江网站虚拟主机公司怎样设计网站
  • 我做的网站在手机里滑动怎么这里卡2014网站建设
  • 大邯郸网站网站建站图片
  • 无锡做网站优化多少钱wordpress产品图片大小不一
  • 吴川手机网站建设公司主页制作语言缩写
  • 做外贸去哪些网站找老外纯 flash 网站
  • 做好的网站网站做管理员消息推送
  • 网站设计公司模板下载网课平台搭建
  • 网站备案过期石家庄最新消息
  • 河源市企业网站seo价格河北邯郸信息港
  • q网站建设wordpress微博头条
  • 个人网站做交易类的赚钱吗江苏廉政建设网站
  • 青岛公路建设集团网站做网站如何用代码把字体变大
  • 网站开发项目建设经验公司邮箱免费注册
  • 做外汇最好的财经网站怎么做网页啊
  • 网站建设教程.网站做图标放在手机桌面
  • 网站开发长沙实验室 wordpress主题
  • 网站上做推广方案数字广东网络建设有限公司介绍
  • 做网站需要的技术 规范哪个网站可以免费制作h5
  • 多用户商城网站建设方案最基本的网站设计
  • 赣州大余做网站建设新浪云 安装wordpress
  • 杭州专业网站制作设计腾讯文件怎么转换wordpress