spring中的循环依赖问题

16 篇文章 0 订阅
14 篇文章 0 订阅

spring中的循环依赖问题

spring应用中,默认是有循环依赖的控制,
场景:
ServiceA、ServiceB、ServieC 多个bean互相依赖,形成闭环。
spring默认使用三级缓存控制循环依赖的问题,但是前提是:
bean不是以构造方法注入,单例bean(多例bean不被spring管理,只管创建)。
spring3级缓存解决循环依赖:
spring构建ServiceA时,发现依赖于ServiceB,
于是先去构造ServiceB的bean,先使用构造方法实例化了一个ServiceA,然后将这个ServiceA放入三级缓存singletonFactories中,接着将这个ServiceA注入到ServiceB中完成ServiceB的创建,将ServiceB放入单例池(singletonObjects,一个ConcurrentHashMap)中,将ServiceA放入二级缓存earlySingletonObjects,最后将单例池中的ServiceB注入到ServiceA中,完成ServiceA的完全创建,放入单例池中。

其中的一个Service使用了@Async注解后:

Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'projectTaskService': Bean with name 'projectTaskService' has been injected into other beans [projectTaskReplyService,materialPlanService] in its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:624)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:207)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.resolveBeanByName(AbstractAutowireCapableBeanFactory.java:454)
	at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.autowireResource(CommonAnnotationBeanPostProcessor.java:543)
	at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.getResource(CommonAnnotationBeanPostProcessor.java:513)
	at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor$ResourceElement.getResourceToInject(CommonAnnotationBeanPostProcessor.java:653)
	at org.springframework.beans.factory.annotation.InjectionMetadata$InjectedElement.inject(InjectionMetadata.java:224)
	at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:116)
	at org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessProperties(CommonAnnotationBeanPostProcessor.java:334)
	... 31 common frames omitted
Disconnected from the target VM, address: '127.0.0.1:56144', transport: 'socket'

使用异步注解的时候,spring的默认实现是生成该类的代理对象,通过代理对象调用异步方法,而现在就造成了该类有了两个代理对象,一个先前已经被注入到了别的bean里去了,一个刚生成的,这就造成了同一类有了不同得两个代理,而spring对bean的属性注入只允许最终代理进行注入,也就是要都以最后一个为准,而先前就已经注入了一个旧的代理,这就造成了错误。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值