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

江都区城乡建设局门户网站163网易企业邮箱入口

江都区城乡建设局门户网站,163网易企业邮箱入口,海洋优质的网站建设,濮阳新闻综合频道回看前言什么是循环依赖呢#xff1f;我们抛开Spring这个框架来聊下什么是循环依赖#xff0c;循环依赖可能在我们平时的开发过程中是属于比较常见的。Spring容器最大的功能就是对bean的生命周期进行管理#xff0c;每个bean在创建的过程中#xff0c;需要得到一个完整的bean需…前言什么是循环依赖呢我们抛开Spring这个框架来聊下什么是循环依赖循环依赖可能在我们平时的开发过程中是属于比较常见的。Spring容器最大的功能就是对bean的生命周期进行管理每个bean在创建的过程中需要得到一个完整的bean需要对bean的所有属性进行赋值如果两个bean出现了相互依赖的情况如果Spring没有处理循环依赖那么出现的结果就是在bean的创建过程中出现相互依赖导致这个bean永远无法创建出来则就导致一直在相互创建那么Spring是如何来解决循环依赖的呢什么情况下会循环依赖1.先看如下demo: B和A相互循环依赖Component public class B {Autowiredprivate A a; }Component public class A {Autowiredprivate B b; }启动项目结果没有报错。 2.加入异步逻辑修改 Component public class A {Autowiredprivate B b;Asyncpublic void test(){} }Component public class B {Autowiredprivate A a; } EnableAsync public class App {public static void main(String[] args) {ApplicationContext ctx new AnnotationConfigApplicationContext(App.class);}}启动后 解决方案加入lazy注解Component public class B {AutowiredLazyprivate A a; } Component public class A {Autowiredprivate B b;Asyncpublic void test(){} }启动后没有异常 上面发现使用Async异步注解循环依赖就会报错有可能是因为有了Async注解修饰的方法其对应的类被代理了那代理了就会报错么我们继续尝试事务注解看看。 Component public class A {Autowiredprivate B b;Transactionalpublic void test(){} }Component public class B {Autowiredprivate A a; } EnableTransactionManagement public class App {public static void main(String[] args) {ApplicationContext ctx new AnnotationConfigApplicationContext(App.class);}}启动后正常没有报错。于是我们不经要问循环依赖本来不会报错为何添加Async异步注解后就会导致报错为何添加Transactional注解就不会报错使用了Async异步注解的循环依赖为何可以使用lazy注解解决我们要想清楚上面的问题就需要了解Bean的生命周期。Bean的生命周期一个简单的Bean生命周期如下 问题出现就属性赋值这里 由图我们知道当B也依赖A时需要去容器中找到AA已经实例化了只是还没属性赋值所以不应该再实例化解决方案在A创建的实例化后用一个map存起来A来不就行了么于是有了二级缓存 似乎上面已经可以解决循环依赖了但细想一下我们会发现问题通过上面的逻辑我们发现了问题所在B赋值属性A时如果从Map中直接获取那么得到的是原生对象如果后续A没有被代理一切没问题如果A被代理了那么B得到的对象就不对了怎么解决如果我们将aop提前是不是解决了问题。 由于A对象的Aop方式提前了那么B依赖的A就是代理对象了A对象执行赋值后后续到Aop这一步会判断是否已经AOP过了是的话就不会再Aop了问题来了:如果C也跟A相互依赖难道C去依赖A时也要通过ObjectFactory获取A的代理对象么如果是这样A就存在2个代理对象了A是单例的因此这样不行于是产生了一个新的缓存我们称之为三级缓存。于是spring似乎完美解决了循环依赖问题但为何使用Async进行异步代理会报错 我们看看报错的原因就知道 那为何Transactional修饰就没问题呢原因是因为ObjectFactory.getObject()方法可以产生代理对象 为何使用lazy注解修饰就能解决问题呢我们看看源码 从源码来看为何Aync注解修饰不能在ObjectFactory.getObject()方法实现代理对象而Tranctional注解相关的处理器那么问题如果A已经在getObject()方法后产生了代理类后续init方法后还会执行代理么答案是不会了因为 总结1、三级缓存各自的作用第一级缓存存的是对外暴露的对象也就是我们应用需要用到的第二级缓存的作用是为了处理循环依赖的对象创建问题里面存的是半成品对象或半成品对象的代理对象第三级缓存的作用处理存在 AOP 循环依赖的对象创建问题能将代理对象提前创建2、Spring 为什么要引入第三级缓存严格来讲第三级缓存并非缺它不可因为可以提前创建代理对象提前创建代理对象只是会节省那么一丢丢内存空间并不会带来性能上的提升但是会破环 Spring 的设计原则Spring 的设计原则是尽可能保证普通对象创建完成之后再生成其 AOP 代理尽可能延迟代理对象的生成所以 Spring 用了第三级缓存既维持了设计原则又处理了循环依赖牺牲那么一丢丢内存空间是愿意接受的
http://www.hkea.cn/news/14461006/

相关文章:

  • 自己做网站制作流程中信建设有限责任公司招投标
  • 沧州企业网站制作的风险网站怎么解决方案
  • 广州网站建设开发公司长沙企业关键词优化服务质量
  • 设计制作公司网站做个英文网站多少钱
  • 苏州网站设计公司排名深圳品牌整合营销
  • 成都网站制作培训多少钱网络营销推广的目的是
  • 规则网站建设网站建设色彩
  • 合肥哪家做网站不错wordpress 百度统计
  • 有关师德建设的网站学建站wordpress
  • 韩国ps教程网站中小工厂erp管理系统
  • 政务网站建设 紧急通知wordpress设置标题颜色
  • 长沙公司制作网站费用郴州市房价
  • wordpress 豆瓣站长之家seo工具包
  • 自适应网站好吗监测网站定制
  • 儿童教育类网站模板下载一级建造师找工作网站
  • 做电子商务网站建设工资多少钱网站开发完了备案
  • 江西城市建设管理协会网站天津市招标投标信息网
  • 网站源码资源什么是网站推广
  • 新竹网站零食网站建设前的市场分析
  • 广东省建设工程安全协会网站wordpress大访问量
  • 定州网站建设安源网站建设
  • 哪里做网站最便宜国际最新军事新闻
  • 厦门网站建设外包科普网站建设方案书
  • 仿网站工具wordpress设置视频图片
  • 福州电商网站设计快手刷评论推广网站
  • wordpress建站模板下载wordpress 不显示主题
  • 网站建设的中期检查表网站怎么做身份验证
  • 使用阿里云建网站绵阳优化网站排名
  • 深圳市城乡住房和建设局网站首页门户网站开发模板
  • 做网站源码要给客户嘛上海搬家公司收费