首页 > 其他分享 >【Spring】三级缓存解决循环依赖问题

【Spring】三级缓存解决循环依赖问题

时间:2023-04-23 11:24:03浏览次数:41  
标签:缓存 对象 Spring 依赖 创建 放入 三级

1、什么是循环依赖

    顾名思义“循环依赖”,举一个简单的例子A中依赖B,B中依赖A,在实例化对象过程中,填充属性阶段A需要B对象,就去创建B对象,创建B对象的时候,发现B依赖了A,于是又去创建A对象,但此时A对象又没有创建结束,一级缓存中找不到,于是线程又去创建一个新的A对象,如此一来,就出现了重复创建的现象,最终会导致内存溢出,JVM报错终止。

2、解决方案

    直接说Spring的解决方案:使用三级缓存。

    设想1:若A、B均为普通对象(这里买下代理对象的伏笔),其实来2级缓存就能解决循环依赖,A提前吧自己的早期对象放到二级缓存中即可

    设想2:若涉及到AOP切面代理的场景,就会有问题,你想,当A创建的时候,把早期A放入2级缓存(这时候AOP还没进行,放入2级缓存的还是原始对象),但是到了B创建的时候,去2级缓存中虽然能找到A的早期对象,但我们都知道,按理说B应该找到A的代理增强对象才对,所以就引出了3级缓存

    三级缓存解决设想2:A创建的时候,把自己的早期工厂对象(你可以想象这个对象有一个getObject方法,可以拿到代理对象)放入三级缓存,后面B创建的时候直接去三级缓存拿这个早期工厂对象,get到之后(若是正常对象拿到的就是正常对象,若是被代理了这里拿到的就是代理对象),直接放到二级缓存,B直接拿二级缓存中的A早期代理对象即可,这样B创建完成,顺理成章A也能创建完成。到此循环依赖解决。

3、再说三级缓存原理

     首先我们还是进行实例化A对象,这个时候,我们要将A的ObjectFactory对象放入Map3中。同样的继续进行属性填充,这个时候B还没创建,于是去创建B。

      那么去实例化B的过程中,我们也是一样的,先把B的ObjectFactory放入Map了中。将B对象放入Map2中。

      继续执行到B的属性填充,去获取A对象,而此时Map1中没有A,因为A还没有创建完成,我们则发现Map了中 有A的ObjectFactory对象,那么我们通过ObjeatFactory对象获取A的早期对象,然后將这个早期对象放入Map2中,同时删除Map3中的A,然后我们将A的引用给了B,那么同样的B对象这个时候也已经完整了。
      接下来我们再把B放入Map中接下来从Map3中删除B。这时候B已经创建完成,A继续执行b的属性填充可以拿到B对象,这样A也完成,最后我们把A对象也放入了Map,删除掉Map2中的A。于是我们的储环依赖就此解决。

标签:缓存,对象,Spring,依赖,创建,放入,三级
From: https://www.cnblogs.com/dk1024/p/17343708.html

相关文章

  • springMVC文件上传
    <%@pagelanguage="java"contentType="text/html;charset=utf-8"pageEncoding="utf-8"%><!DOCTYPEhtmlPUBLIC"-//W3C//DTDHTML4.01Transitional//EN""http://www.w3.org/TR/html4/loose.dtd"><......
  • Mybatis缓存
    1.Mybatis缓存1.1. 理解MyBatis缓存正如大多数持久层框架一样,MyBatis 同样提供了一级缓存和二级缓存的支持1.     一级缓存: 基于PerpetualCache 的 HashMap本地缓存,其存储作用域为 Session,当 Sessionflush 或 close 之后,该Session中的所有 Cache 就将清空。2......
  • spring整合jpa优化
    本篇是针对上一篇《spring整合jpa》文章进行优化1.1.  使用接口代替dao层1.1.1.   删除IpersonDao和PersonDaoImpl1.1.2.   新建PersonDao.javaPersonDao.javapackagecom.morris.dao;importorg.springframework.data.repository.Repository;importcom.morris.enti......
  • spring AOP和通知
    1.  spring的通知1.1. AOP的概念切面(Aspect):一个关注点的模块化,这个关注点可能会横切多个对象。事务管理是J2EE应用中一个关于横切关注点的很好的例子。在SpringAOP中,切面可以使用基于模式或者基于注解的方式来实现。连接点(Joinpoint):在程序执行过程中某个特定的点,比如某方法调......
  • Spring与Hibernate的整合
    1.Spring与Hibernate的整合1.1.在Spring容器中创建SessionFactory为了避免硬编码的资源查找与应用程序对象紧密耦合,Spring允许你在Spring容器中以bean的方式定义诸如JDBCDataSource或者HibernateSessionFactory的数据访问资源。任何需要进行资源访问的应用程序对象只需要持有......
  • spring mvc一个Controller响应多个请求
    1.1. 控制器的实现packagecom.morris.controller;importjavax.servlet.http.HttpServletRequest;importjavax.servlet.http.HttpServletResponse;importorg.springframework.web.servlet.ModelAndView;importorg.springframework.web.servlet.mvc.multiaction.Multi......
  • spring集成Hessian
    1.1.1.   编写远程接口Ihello.javapackagecn.tempus.hessian;publicinterfaceIHello{publicStringsayHello(Stringname);}1.1.2.   编写远程接口实现类HelloImpl.javapackagecn.tempus.hessian;importcom.caucho.hessian.server.HessianServlet;......
  • spring mvc注解基本配置
    1.1. 配置web.xml<?xmlversion="1.0"encoding="UTF-8"?><web-appxmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns="http://java.sun.com/xml/ns/javaee"xsi:schemaLocation="http://java.sun.com/xm......
  • 【spring boot】 重启kafka客户端连接
    背景kafka服务端重建时,kafka客户端会连不上kafka服务端,此时需要重启客户端重连代码实现@ServicepublicclassKafkaConsumerService{privateKafkaConsumer<String,String>consumer;@AutowiredprivateKafkaPropertieskafkaProperties;//在应用......
  • Spring缓存注解的使用与源码分析
    SpringCache提供了一个对缓存使用的抽象,以及大量的实现方便开发者使用。SpringCache主要提供了如下注解:注解说明@Cacheable根据方法的请求参数对其结果进行缓存@CachePut根据方法的请求参数对其结果进行缓存,和@Cacheable不同的是,它每次都会触发真实方法的调用@CacheEvict根据一定......