springboot循环依赖问题处理
-
发现问题
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled. 2024-11-27 21:30:58.695 [f8cd6df4693e404aa607363bbe3dcf00] [main] ERROR o.s.boot.SpringApplication - - Application run failed org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'contextBaseRegistryConfiguration': Unsatisfied dependency expressed through field 'groupQrTaskDetailsService'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'groupQrTaskDetailsServiceImpl': Unsatisfied dependency expressed through method 'setSyyyAccountService' parameter 0; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'syyyAccountServiceImpl': Bean with name 'syyyAccountServiceImpl' has been injected into other beans [standardTaskServiceImpl] 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 'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:660)at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:640)at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:119)at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1413)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:601)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524)at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:944)at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:918)at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:583)at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145)at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754)at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:434)at org.springframework.boot.SpringApplication.run(SpringApplication.java:338)at org.springframework.boot.SpringApplication.run(SpringApplication.java:1343)at org.springframework.boot.SpringApplication.run(SpringApplication.java:1332)at com.jd.bpo.jingxiaoge.api.JingxiaogeApiApp.main(JingxiaogeApiApp.java:39) Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'groupQrTaskDetailsServiceImpl': Unsatisfied dependency expressed through method 'setSyyyAccountService' parameter 0; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'syyyAccountServiceImpl': Bean with name 'syyyAccountServiceImpl' has been injected into other beans [standardTaskServiceImpl] 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 'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.resolveMethodArguments(AutowiredAnnotationBeanPostProcessor.java:768)at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.inject(AutowiredAnnotationBeanPostProcessor.java:720)at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:119)at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:399)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1413)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:601)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524)at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276)at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1380)at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1300)at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:657)... 20 common frames omitted Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'syyyAccountServiceImpl': Bean with name 'syyyAccountServiceImpl' has been injected into other beans [standardTaskServiceImpl] 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 'getBeanNamesForType' with the 'allowEagerInit' flag turned off, for example.at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:631)at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:524)at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276)at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1380)at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1300)at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredMethodElement.resolveMethodArguments(AutowiredAnnotationBeanPostProcessor.java:760)... 34 common frames omitted
-
分析问题
从最后一行看问题:Error creating bean with name ‘syyyAccountServiceImpl’: Bean with name ‘syyyAccountServiceImpl’ has been injected into other beans [standardTaskServiceImpl] in its raw version as part of a circular reference
说明在standardTaskServiceImpl bean中注入的syyyAccountServiceImpl,导致循环依赖了。如下:
-
解决问题
可能的解决方案:-
重构代码以消除循环依赖:
将某些依赖改为方法注入: 如果可能,使用方法注入而不是构造函数注入,这样可以延迟依赖的解决,直到bean实际需要它为止。
引入一个中间层: 通过引入一个新的服务或者将某些功能拆分到不同的类中,以消除循环依赖。 -
使用@Lazy注解:
在一个或多个依赖的bean上加上@Lazy注解,这会告诉Spring在需要时再初始化这个bean,而不是在启动时立即初始化。例如:
-
考虑使用ApplicationContext手动获取Bean:
在需要的地方,通过ApplicationContext获取bean,这样避免了自动注入带来的循环依赖问题。
-