首页 > 其他分享 >Spring三级缓存与解决循环依赖

Spring三级缓存与解决循环依赖

时间:2023-03-19 16:33:07浏览次数:36  
标签:缓存 依赖 Spring 二级缓存 循环 单例 AOP 三级

一、什么是循环依赖、一级缓存

A、B两个Service相互依赖,类似于死锁,我们来看AServiceBean的生命周期

 

 

我们要填充bService时,在单例池找不到B,就会先去创建B。但是创建B的时候,触发B的Bean的生命周期,在单例池也找不到A,产生循环依赖。

那么怎么处理呢,就需要打破依赖

 

 spring在2.2步解决了循环依赖

 

但是在4有问题

 

 因为AOP的话,时将AService的普通对象赋值给AService的代理对象,最后加入单例池中的是AService的代理对象,所以和2.2把AService的普通对象给了B,有问题,怎么解决呢?

 

所以我们可以将原本的AOP过程提前,在第一步的时候就进行AOP

 

 

但是正常情况下是在4进行AOP,在1的时候怎么知道判断发生了AOP呢?

----判断不了,所以我们将AOP的过程放到2.2步

 

 

========================================

另一种情况,如果A也需要填充C,那么C也会在单例池找不到A的情况下,发现产生循环依赖了,立马生成一个AService的代理对象来进行注入吗?因为A是单例Bean,所以不可能。那么怎么解决呢,能不能把A的代理对象放到单例池吗?

肯定不能,因为没有经历过全部生命周期。

所以我们可以放到二级缓存

 

 

二、二级缓存

用来保存没有经过完整生命周期,但需要给其它单例Bean用的单例Bean

 

 我们在创建C的时候,我们可以从二级缓存找到A的AOP代理对象,而B找不到,因为还没有放入到二级缓存

但是还是回到原来的问题,二级缓存也没有打破循环

 

 

三、三级缓存(单例工厂)

是为了打破循环

三级缓存是开始实例的时候,先添加一个lambda表达式,在2.2发现有循环依赖后,执行lambda表达式,其最终执行的是

 

 

判断是否要进行切面,如果要进行切面,则进行aop,否则返回普通对象

 

 

 

四、什么样的循环依赖spring解决不了

有参构造,因为普通对象根本创建不出来

public class A {
    private B b;

    public A(B b) {
        this.b = b;
    }
}

public class B {
    private A a;

    public B(A a) {
        this.a = a;
    }
}

 

 

五、为什么加@Lazy可以解决

根本进不去循环,就像ModelAndView对象一样,Spring容器直接创造了一个B代理对象返回给A

 

六、三个缓存分别用的什么数据结构,为什么

一级缓存使用ConcurrentHashMap,可以支持高并发读写;二级缓存使用ConcurrentHashMap,可以避免循环依赖时的死循环问题;三级缓存使用ConcurrentHashMap和HashSet,可以支持快速的查找和删除操作。

 

标签:缓存,依赖,Spring,二级缓存,循环,单例,AOP,三级
From: https://www.cnblogs.com/wintermist/p/17233504.html

相关文章

  • Spring框架学习
    只有到找工作的时候才想得起来写博客的warobot是屑...以下内容整理自w3school: Spring三层架构web表现层service业务层dao持久层 Spring的优良特性......
  • 第五天(SpringBoot基础第二篇)
    一、关于starterstater参赛人、发令员SpringBoot中的starter只是把我们某一模块,比如web开发时所需要的所有JAR包打包好给我们而已。不过它的厉害之处在于,能自动把......
  • 第四天(springBoot基础第一篇)
    springBoot基础1.什么是springBoot(概念及其特点)1.概念(1)介绍官网地址: https://spring.io/SpringBoot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应......
  • 本地缓存 GuavaCache & Caffeine
    1.GuavaCacheGuavaCache是一個全内存的本地缓存实现,提供了线程安全实现机制1.1GuavaCache数据结构底层类似ConcurrentlHashMap,所以是线程安全的(分段锁)  1.2Gu......
  • 【MyBatis框架】mybatis和spring整合
    spring和mybatis整合1.整合思路需要spring通过单例方式管理SqlSessionFactory。spring和mybatis整合生成代理对象,使用SqlSessionFactory创建Sql......
  • 【MyBatis框架】查询缓存-一级缓存原理
    查询缓存1.什么是查询缓存mybatis提供查询缓存,用于减轻数据压力,提高数据库性能。mybaits提供一级缓存,和二级缓存。缓存模式图如图一级缓存是......
  • 【hibernate框架】缓存机制之二级缓存
    二级缓存是sessionFactory级别的缓存,可以跨越session存在。hibernate文档里关于二级缓存的说明:二级缓存(TheSecondLevelCache)hibernate支持......
  • 【hibernate框架】缓存机制之一级缓存
    什么是缓存:我们在内存中开辟一块空间,把本来应该存储在硬盘上的东西,然后给它放在内存里,将来要读的时候从内存中读,这个部分就叫做缓存。在hibernate......
  • 【spring框架】spring之HibernateTemplate
    HibernateTemplate是spring对hibernate使用的一个简单封装:i.设计模式TemplateMethod模板方法ii.Callback回调(钩子函数)一般我们写save方法都......
  • 【spring框架】spring之packagesToScan
    spring的spring.jar的jar包内,在org.springframework.orm.hibernate3.annotation下,有一个AnnotationSessionFactoryBean类,其中有一个属性叫做"packages......