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

电商网站平台有哪些功能模块应用软件和嵌入式软件的区别

电商网站平台有哪些功能模块,应用软件和嵌入式软件的区别,大学什么专业是学网站开发的,干煤棚网架公司在Spring框架中,循环依赖(Circular Dependency)是指多个Bean相互依赖,形成一个循环引用。例如,Bean A依赖于Bean B,而Bean B又依赖于Bean A。这种情况在Bean创建时可能导致Spring容器无法正常完成初始化&am…

在Spring框架中,循环依赖(Circular Dependency)是指多个Bean相互依赖,形成一个循环引用。例如,Bean A依赖于Bean B,而Bean B又依赖于Bean A。这种情况在Bean创建时可能导致Spring容器无法正常完成初始化,抛出错误,如下:

public class A {private final B b;public A(B b) {this.b = b;}
}public class B {private final A a;public B(A a) {this.a = a;}
}

启动时会出现如下错误:

org.springframework.beans.factory.BeanCurrentlyInCreationException:
Error creating bean with name 'A': Requested bean is currently in creation: Is there an unresolvable circular reference?

一、解决循环依赖的方法

1. 构造器注入

构造器注入不支持循环依赖,因为Spring在创建Bean时需要解析所有构造函数参数,这导致了依赖循环。可以通过使用@Lazy注解延迟Bean的初始化来解决此问题,@Lazy会告诉Spring在第一次使用Bean时才初始化,而不是立即初始化。

@Component
public class A {private final B b;@Autowiredpublic A(@Lazy B b) {this.b = b;}
}@Component
public class B {private final A a;@Autowiredpublic B(@Lazy A a) {this.a = a;}
}
2. Setter注入

Setter注入可以解决循环依赖,因为Spring可以先创建Bean的实例,再注入其依赖。

public class A {private B b;public void setB(B b) {this.b = b;}
}public class B {private A a;public void setA(A a) {this.a = a;}
}
3. 使用@Autowired注解

可以使用@Autowired进行Setter注入或字段注入,同样可以解决循环依赖问题。

public class A {@Autowiredprivate B b;
}public class B {@Autowiredprivate A a;
}
4. 使用@Lazy注解

@Lazy注解可以延迟Bean的初始化,避免循环依赖。

public class A {@Autowired@Lazyprivate B b;
}public class B {@Autowired@Lazyprivate A a;
}
5. 使用ObjectFactory或Provider

使用ObjectFactoryProvider可以在需要时才获取Bean实例,从而解决循环依赖。

public class A {@Autowiredprivate ObjectFactory<B> bFactory;public void someMethod() {B b = bFactory.getObject();// 使用B}
}public class B {@Autowiredprivate ObjectFactory<A> aFactory;public void someMethod() {A a = aFactory.getObject();// 使用A}
}
6. 配置allow-circular-references: true

通过allow-circular-references: true配置来允许Spring容器处理Bean之间的循环依赖问题,但从设计角度来看,尽量避免循环依赖更为合理。

spring:main:allow-circular-references: true

 二、Spring三级缓存解决循环依赖的原理

Spring在创建Bean时使用三级缓存来处理循环依赖问题。整个过程分为三个阶段:

  1. 实例化:创建Bean实例,对应于AbstractAutowireCapableBeanFactorycreateBeanInstance方法。
  2. 属性注入:为实例化的Bean注入属性,对应于populateBean方法。
  3. 初始化:执行Bean的初始化操作,对应于initializeBean方法,完成AOP代理等。

Spring使用三级缓存的策略如下:

  • 一级缓存(singletonObjects):存储已经完全初始化的单例Bean。
  • 二级缓存(earlySingletonObjects):存储早期的Bean对象,未完全初始化时放入该缓存。
  • 三级缓存(singletonFactories):存储Bean工厂ObjectFactory,用于创建Bean的早期引用。

缓存的工作流程如下:

  1. 创建Bean实例:Spring首先尝试从一级缓存singletonObjects中获取Bean,如果没有则尝试从二级缓存earlySingletonObjects获取。如果依然没有找到,则从三级缓存singletonFactories获取。
  2. 提前曝光Bean:当Spring检测到循环依赖时,会将Bean的早期引用(通过ObjectFactory创建的代理对象)放入三级缓存。
  3. 解决循环依赖:当另一个Bean需要依赖尚未完全初始化的Bean时,Spring会从三级缓存中获取其早期引用,并将其放入二级缓存。
  4. 完成初始化:当Bean完全初始化后,Spring会将其移至一级缓存,确保Bean的正常使用。

图解分析:对于通过构造器注入相互依赖的两个类A和B,Spring的处理步骤如下:

  1. 创建A时,因A依赖B,Spring将A的早期引用放入三级缓存。
  2. 创建B时,因B依赖A,Spring从三级缓存中获取A的早期引用。
  3. B初始化完成后,B的实例放入一级缓存。
  4. A随后也完成初始化,并将其实例放入一级缓存。

三、为什么Spring使用三级缓存而不是二级缓存?

  1. 代理对象的创建:某些场景(如AOP)需要在Bean初始化的后期生成代理对象。如果仅使用二级缓存,代理对象的创建可能会在Bean未完全初始化时进行,导致代理不完整。三级缓存中的ObjectFactory可以确保在需要时动态生成代理对象。

  2. 延迟创建早期引用:三级缓存允许Spring延迟创建早期引用,从而在特殊场景下实现灵活的依赖处理,避免了Bean在完全初始化前被错误引用。

三级缓存机制为Spring处理复杂的依赖关系提供了灵活性和可靠性,同时保证了Bean初始化和代理生成的顺序。

http://www.yayakq.cn/news/869543/

相关文章:

  • 网站建设平台有哪些 谢谢平台建站电子商务专业网站
  • 视频网站开发问题wordpress vantage主题
  • 移动端网站提交提交上海松江区网站建设
  • 免费软件下载网站群晖wordpress默认地址
  • 浙江临海市建设局网站做网站详情的图片
  • 南京网站建设包括哪些怎么做交易猫钓鱼网站
  • 海口制作网站软件网站建设360元起全包
  • 网站建设 签约信息网络营销的核心是
  • 响应式网站建设一般多少钱网站开发精灵
  • 网站建设后百度找不到南宁 网站设计
  • 网站开发前端指什么软件域名解析后如何建设网站
  • 搭建网站视频教程做英文企业网站
  • 建网站主机asp sqlserver做网站
  • 机械设备行业网站建设济南营销型网站建设哪家好
  • 泰安医院网站建设成都网站建设3六六
  • 自助建站最好的平台响应式学校网站模板下载
  • 知名做网站费用《民用建筑通用规范》
  • 深圳有多少网站建设公司经营地址怎么在国税网站做更改
  • 西安建设局网站地址网站建设制作服务
  • 银川迅雷网站建设制作华为手机网站建设规划书
  • 苏州网站制作方法天津外贸seo推广
  • 外贸网站如何做推广多少钱网站建设与管理找工作
  • 建网站什么样的域名最好温州seo优化网络推广
  • 网站开发模板教务管理wordpress自定义字段位置
  • 视频短链接生成器优化大师如何删掉多余的学生
  • 怎么用wordpress搭建网站做展馆好的设计网站
  • 建设网站需要多少钱济南兴田德润厉害吗七台河建网站
  • 做产品宣传网站多少钱做高清视频的网站
  • 东莞企业网站建设费用外贸工艺品网站建设
  • 教务在线网站开发报告书新手建什么网站赚钱