循环依赖问题和代理导致的事务失效问题

67 阅读2分钟

循环依赖问题

在 Spring 中,如果一个 bean 尝试将自身引用注入到自身中,通常会引发循环依赖

创建A实例--》初始化A--》注入B--》创建B实例--》初始化B--》注入A

假设两个依赖在初始化A时需要注入B,要注入B就需要创建B实例再初始化B,而在初始B时需要注入A,此时A还没有创建完成就陷入死循环。

SpringBoot自动化解决循环依赖问题(不优先推荐)

Spring会延迟初始化,B需要注入A,此时Spring会先实例化A,把一个半成品A注入给B,延迟A的初始化。

具体流程入下:

目标创建A【要注入B】(Spring检测到循环依赖) ->A先实例化,没有初始化 [创建A的工厂到三级缓存] ->从容器中获取并注入B ->初始化B【实例化B,注入A】[进入二级缓存] ->从三级缓存中获取创建A的工厂,获取到A的半成品对象,放入到二级缓存中,删除三级缓存中的创建A的工厂【得到一个半成品A】 ->于是B就初始化完成了,把B从二级缓律中移动到一级缓存中,B就完成了初始化,是一个完整的bean[删除三级缓存工厂] ->继续完成A的初始化,从一级缓存中获取注到B,注入A,把A从二级缓存中移动到一级缓存中,A就完成了初始化. [删除二级缓存工厂] [完成]

手动解决循环依赖问题:(优先推荐)

AOP+自定义注解动态代理解决问题

内部是一个Lambda表达式来完成代理对象的创建.创建完成后,会放入到它的上一级缓存中。而在依赖注入时,会从一级缓存开始查找。在前面找到,就不会到三级缓存(创建)

间接错开直接引入

AB两个服务,需要两个服务相互引用,解决直接引入导致的循环依赖

AService注入BServiceBService注入AMapper

Spring事务失效问题

Spring进行事务控制是通过代理对象进行的,在调用注解方法之前开启事务,方法执行结束后提交事务。

而若调用过程中,未使用接口去执行事务方法,则会引入类方法来实现事务,所以不被Spring识别,不能完成方法提交事务,所以只需要通过代理对象去调用add方法.即方法通过接口调用实现代理,进而提交数据, 完成事务.