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

检测网站名 注册深圳专业网站建设制作价格

检测网站名 注册,深圳专业网站建设制作价格,娱乐网站建设方案,如何开发游戏辅助软件循环依赖是指多个Bean之间互相依赖#xff0c;形成一个闭环的情况。这种情况可能会导致系统无法正常初始化或运行#xff0c;因此需要一种机制来解决循环依赖问题。 Spring解决循环依赖问题的核心思想是延迟注入和三级缓存机制。下面详细介绍这些概念#xff1a; 1. 延迟注…循环依赖是指多个Bean之间互相依赖形成一个闭环的情况。这种情况可能会导致系统无法正常初始化或运行因此需要一种机制来解决循环依赖问题。 Spring解决循环依赖问题的核心思想是延迟注入和三级缓存机制。下面详细介绍这些概念 1. 延迟注入Lazy Initialization Spring默认情况下是延迟注入Bean的属性的这意味着Spring在实例化Bean时不会立即注入它们的属性引用。相反它会先创建一个尚未完成初始化的Bean实例然后将这个实例放入一个早期单例缓存中。这个Bean实例已经包含了对其他Bean的引用但是属性还没有被注入。这样Spring就避免了循环依赖的直接发生。 2. 三级缓存机制 Spring引入了三级缓存机制用于处理Bean的实例化和属性注入过程中的循环依赖。 singletonObjects这是Spring容器的一级缓存用于存储已经完成初始化和属性注入的单例Bean实例。这些Bean可以被其他Bean引用。earlySingletonObjects这是Spring容器的二级缓存用于存储已经实例化但属性注入尚未完成的Bean实例。这个缓存是为了解决循环依赖问题而存在的。在这个缓存中Bean实例包含了对其他Bean的引用但属性注入还没有完成。singletonFactories这是Spring容器的三级缓存用于存储Bean的工厂方法。当Bean需要被初始化时Spring会使用工厂方法来创建Bean并将Bean实例放入这个缓存中。这个缓存也是为了解决循环依赖问题而存在的。 整个循环依赖解决过程如下 首先Spring创建Bean的实例但不进行属性注入将Bean放入earlySingletonObjects缓存中。接着Spring开始属性注入过程如果发现需要注入的属性是其他Bean的引用它会尝试从singletonObjects缓存中获取已经初始化的Bean实例如果没有找到就会继续递归初始化该Bean此时将使用singletonFactories缓存来创建Bean的实例同时将Bean实例放入earlySingletonObjects缓存中。当Bean的属性注入完成后Bean实例将从earlySingletonObjects缓存中移除然后放入singletonObjects缓存中表示该Bean已经完成初始化可以被其他Bean引用。如果发现循环依赖Spring会抛出异常因为无法解决的循环依赖问题会导致无限递归。 总之Spring的延迟注入和三级缓存机制有效地解决了循环依赖问题允许程序员在配置依赖关系时更自由地引用其他Bean同时保证了Bean的初始化顺序和完整性。但要注意合理的Bean设计和依赖管理仍然是避免循环依赖问题的最佳实践。 示例 我们将使用以下三个类Customer、Order 和 Product。 public class Customer {private String name;private Order order;public Customer(String name) {this.name name;}public void setOrder(Order order) {this.order order;}public void printDetails() {System.out.println(Customer Name: name);System.out.println(Order Details:);order.printOrder();} }public class Order {private Product product;public void setProduct(Product product) {this.product product;}public void printOrder() {System.out.println(Product Details:);product.printProduct();} }public class Product {private String name;public Product(String name) {this.name name;}public void printProduct() {System.out.println(Product Name: name);} }现在让我们看看如何在 Spring 中配置这些 Bean以及如何解决潜在的循环依赖问题。 spring-config.xml bean idcustomer classcom.example.Customerconstructor-arg valueJohn / /beanbean idorder classcom.example.Orderproperty nameproduct refproduct / /beanbean idproduct classcom.example.Productconstructor-arg valueLaptop / /bean在这个示例中Customer 依赖于 OrderOrder 依赖于 Product同时 Product 依赖于 Customer形成了循环依赖。 Spring 会采用类似前面描述的方式来解决循环依赖 首先Spring 实例化 Customer但不注入 Order。然后Spring 实例化 Order但不注入 Product。接下来Spring 实例化 Product。现在Spring 开始属性注入过程。它尝试为 Customer 注入 Order从缓存中找不到因此继续实例化 Order。这时Order 已经实例化但还未注入 Product。Spring 为 Order 注入 Product从缓存中找不到继续实例化 Product。此时Spring 为 Product 注入 Customer从缓存中找到已经实例化的 Customer。属性注入完成后所有 Bean 都会从早期缓存中移除放入单例缓存中。 最终Spring 成功解决了这个复杂的循环依赖问题并且可以正常打印 Customer、Order 和 Product 的详细信息。 需要注意的是虽然 Spring 可以解决循环依赖但在设计应用程序时仍然建议尽量避免复杂的循环依赖关系以保持代码的清晰性和可维护性。 三级缓存提前暴露对象aop 总什么是循环依赖问题A依赖BB依赖CC依赖A 分先说明bean得创建过程实例化初始化填充属性 1.先创建A对象实例化A对象此时A对象中的b属性为空 2.从容器中查找B对象如果找到了直接赋值不存在循环依赖问题(不通)找不到直接创建B对象 3.实例化B对象此时B对象中的a属性为空填充属性a 4.从容器中查找A对象找不到直接创建 此时如果仔细琢磨的话会发现A对象是存在的只不过此时的A对象不是一个完整的状态只完成了实例化但是未完成初始化如果在程序调用过程中拥有了某个对象的引用能否在后期给他完成赋值操作可以优先把非完整状态的对象优先赋值等待后续操作来完成赋值相当于提前暴露了某个不完整对象的引用所以解决问题的核心在于实例化和初始化分开操作这也是解决循环依赖问题的关键 当所有的对象都完成实例化和初始化操作之后还要把完整对象放到容器中此时在容器中存在对象的几种状态完成实例化但未完成初始化完整状态因为都在容器中所以要使用不同的map结构来进行存储此时就有了一级缓存和二级缓存如果一级缓存中有了那么二级缓存中就不会存在同名的对象因为他们的查找顺序是123这样的方式来查找的。一级缓存中放的是完整对象二级缓存中放的是非完整对象 为什么需要三级缓存 三级缓存的value类型是ObjectFactory是一个函数式接口存在的意义是保证在整个容器的运行过程中同名的bean对象只能有一个。 如果一个对象需要被代理或者说需要生成代理对象那么要不要优先生成一个普通对象要 普通对象和代理对象是不能同时出现在容器中的因此当一个对象需要被代理的时候就要使用代理对象覆盖掉之前的普通对象在实际的调用过程中是没有办法确定什么时候对象被使用所以就要求某个对象被调用的时候优先判断此对象是否需要被代理类似于一种回调机制的实现因此传入lambda表达式的时候可以通过lambda表达式来执行对象的覆盖过程getEarlyBeanReference() 因此所有的bean对象在创建的时候要优先放到三级缓存中在后续的使用过程中如果需要被代理则返回代理对象如果不需要被代理则直接返回普通对象 以下是一个简单的Java代码示例演示了Spring中的循环依赖以及Spring是如何解决它的。这个示例包含两个类Person 和 AddressPerson 类依赖于 Address而 Address 类也依赖于 Person。 import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component;Component public class Person {private String name;private Address address;Autowiredpublic Person(Address address) {this.address address;}public void setName(String name) {this.name name;}public String getName() {return name;}public Address getAddress() {return address;} }Component public class Address {private String city;private Person person;Autowiredpublic Address(Person person) {this.person person;}public void setCity(String city) {this.city city;}public String getCity() {return city;}public Person getPerson() {return person;} }在这个示例中Person 和 Address 类都使用了构造函数注入它们互相依赖对方。现在让我们分析一下Spring是如何解决这个循环依赖的 当Spring容器启动时它首先创建一个 Person 对象并放入一级缓存singletonObjects缓存但尚未完成初始化。接下来Spring创建一个 Address 对象并将 Person 对象注入到 Address 对象中。在注入时它发现 Person 对象已经在一级缓存中但尚未完成初始化。因此它创建一个 Person 的代理对象并将它注入到 Address 对象中然后将 Address 对象放入二级缓存earlySingletonObjects缓存。Person 对象的初始化过程继续它的构造函数完成并将 Address 对象注入。在注入时Spring发现 Address 对象已经在二级缓存中但尚未完成初始化。因此它创建一个 Address 的代理对象并将它注入到 Person 对象中。Address 对象的初始化过程继续它的构造函数完成。此时Address 对象和 Person 对象都已完成初始化。最终Spring将 Person 和 Address 对象放回一级缓存以供其他Bean使用。代理对象被替换为真正的对象。 这样Spring成功解决了 Person 和 Address 之间的循环依赖通过创建代理对象使得初始化过程可以顺利完成。
http://www.zqtcl.cn/news/368903/

相关文章:

  • 网站开发培训班多少报名费安徽省建设工程信息网站
  • 旅游网站规划设计余姚网站公司
  • 广州市地铁站地图dede增加手机网站
  • dede 网站名称 空的网站开发行业新闻
  • 网站开发费用做账升级系统
  • 外贸公司网站制作价格网络公司的经营范围有哪些
  • 东莞三合一网站制作海南省生态文明村建设促进会网站
  • 邯郸做企业网站设计的公司福田祥菱m2
  • 手表拍卖网站动漫做暧视频网站
  • 福州网站定制公司如何做p2p网站
  • 微信外链网站开发嘉兴市城市建设门户网站
  • 在手机上如何制作网站qq注册网页入口
  • asp.net程序做的网站安全吗国内什么网站用asp.net
  • 凡科网做网站网站编辑知识
  • c#做交易网站taxonomy wordpress
  • 统一门户网站开发员给我用织梦做的网站
  • 网站上有声的文章是怎么做的深圳市住房和建设局网站和市住宅租赁管理服务中心
  • 如何对网站进行爬虫页面设计存在的问题
  • 知名网站建设加盟合作企业邮箱如何登录
  • asp net mvc做网站软文推广是什么
  • 张家口住房和城乡建设厅网站如何做点击赚钱的网站
  • 网站在建设中无法访问贵州碧江区住房和城乡建设局网站
  • 营销类网站 英文东莞正规的免费网站优化
  • 柳州网站推广最好的公司百度seo优化培训
  • 哈尔滨门户网站建站哪个网站做农产品
  • 网站行业关键词如何建设网站
  • wordpress插件目录504wordpress访问优化插件
  • 固定ip做网站网页源码提取工具
  • php网站模板源码下载公司网络营销推广软件
  • 免费电子版个人简历模板温州快速排名优化