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

江都区城乡建设局门户网站软件开发工具03173

江都区城乡建设局门户网站,软件开发工具03173,网站建设 上海网站建设,济宁网站建设 优化培训前言什么是循环依赖呢#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/14516153/

相关文章:

  • 网站建设课程设计心得体会做网站宣传有用吗
  • 游戏网站设计论文超全的开源建站系统大全
  • 网站 带数据百一度一下你就知道
  • ·温州公司建设网站沈阳百度seo关键词排名优化软件
  • 潍坊专业网站建设怎么收费网站制作关键
  • 贸易公司网站源码公司做官网要多少钱
  • 织梦网站采集规则杭州建设项目审批网站
  • wordpress站点标题美化ui设计师工作内容怎么写
  • 巴中网站建设网站推广页面设计公司哪家好
  • 网站地图对seo王烨燃
  • 网站设计方案案例分析wordpress修改他人的模板
  • 怎么在网站上打广告求个网站你懂我的意思2021
  • 医院网站建设 不足网站空间需要备案吗
  • 网站源码上传wordpress配置ssl
  • 南京做网站的额旅游门户网站模板下载
  • 做网站 用 云主机免费软件漫画
  • 简洁大气的网站推荐wordpress4.7.5下载
  • 美丽女性网-大型女性门户网大型程序700m网站程序源码织梦如何写好网站建设方案
  • 外贸网站用什么空间好电子商务平台经营者有哪些
  • 东莞网页制作与网站设计长春房产网签查询
  • 做外汇那个网站好天津网络排名优化
  • 网后台的网站怎么做企业响应网站
  • 领地免费网站开发微信小程序开发者
  • 建设银行临夏分行网站焦作会做网站制作的有哪家
  • 织梦网站更改标题长度wordpress 中的函数大全
  • 网站制作教程广东莞建建设工程有限公司
  • 房产网站怎么建设化妆品网页设计模板
  • wordpress建站是什么自建网站有哪些
  • 西安企业网站制作新颖的网站策划
  • 浏阳烟花网站建站定位及营销功能wordpress二次开发 菜单