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

高端响应式网站建设百度如何发布信息推广

高端响应式网站建设,百度如何发布信息推广,小程序到哪里去找,制作网站的模板下载前言什么是循环依赖呢?我们抛开Spring这个框架来聊下什么是循环依赖,循环依赖可能在我们平时的开发过程中是属于比较常见的。Spring容器最大的功能就是对bean的生命周期进行管理,每个bean在创建的过程中,需要得到一个完整的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 {@Autowired@Lazyprivate 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);}}

启动后:正常,没有报错。

于是我们不经要问:

  1. 循环依赖本来不会报错,为何添加@Async异步注解后就会导致报错

  1. 为何添加@Transactional注解就不会报错

  1. 使用了@Async异步注解的循环依赖,为何可以使用@lazy注解解决

我们要想清楚上面的问题,就需要了解Bean的生命周期。

Bean的生命周期

一个简单的Bean生命周期如下:

问题出现就属性赋值这里:

由图:我们知道,当B也依赖A时,需要去容器中找到A,A已经实例化了,只是还没属性赋值,所以,不应该再实例化,解决方案:在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.khdw.cn/news/39163.html

相关文章:

  • 网站链接锚点怎么做竞价开户公司
  • 广东民航机场建设有限公司网站百度游戏排行榜
  • 做qq链接的网站朝阳区seo
  • 苏州网站建设软件收费微信朋友圈广告推广
  • 阿里云虚拟主机可以做几个网站百度网盘下载电脑版官方下载
  • 自己建立独立域名的网站怎么做互联网广告
  • 网站建设需求文案企业网站管理系统源码
  • 做网站是什么职位上海百度移动关键词排名优化
  • 怎么做购物型网站济南全网推广
  • 上海利恩建设集团有限公司网站淘宝推广
  • 电商网站的开发形式抖音视频排名优化
  • 包头做网站的2023年8月新冠疫情
  • 江苏网站建设南通短视频拍摄剪辑培训班
  • 广告机自建站模板如何推广小程序平台
  • 能在线做英语题目的网站渠道推广平台
  • 网站怎么换域名营销方式有哪些
  • 鞍山做百度网站一年多少钱自媒体人15种赚钱方法
  • 移动端购物网站建设目的数据网站
  • 即时设计网站爱站工具包
  • 移动电子商务网站建设研究网络推广公司是做什么的
  • 中卫网站建站设计网站建设公司地址在哪
  • 免费下载网站建设方案ppt营销渠道的三个类型
  • wordpress登录没反应成都抖音seo
  • 品牌网站的推广电商网站上信息资源的特点包括
  • 静态网站开发实验报告个人如何建立免费网站
  • 临海手机网站企业官网建站
  • 网站制作 手机淘宝推广费用一般多少
  • 动漫网站建设方案设计站长工具端口查询
  • 网站制作报价开怎么seo快速排名
  • dede重工蓝色企业免费网站模板关键词优化seo优化排名