您现在的位置是:网站首页 > 代码编程 > JAVA开发JAVA开发
【原】SpringBoot使用@Async注解导致循环依赖的原因及解决方案
不忘初心 2019-09-12 围观() 评论() 点赞() 【JAVA开发】
简介:最近在项目中,用了@Async注解之后导致循环依赖报错,但是在我的印象中,spring是允许循环以来的,换句话说,spring自身是已经解决了循环依赖这个问题的,但是在这里竟然又出现了。详细信息如下,在注入bean的时候报错了:Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Err
最近在项目中,用了@Async注解之后导致循环依赖报错,但是在我的印象中,spring是允许循环以来的,换句话说,spring自身是已经解决了循环依赖这个问题的,但是在这里竟然又出现了。
详细信息如下,在注入bean的时候报错了:
Caused by: org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'personalService': Bean with name 'personalService' has been injected into other beans [groupService,userServiceImpl] 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:605)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:498)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:273)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1239)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1166)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:593)
... 79 common frames omitted
开始一直去找循环依赖,导致耽误了很多时间,后来确认代码就是加了异步注解之后,顺着@Async注解这个方向去查找问题,最终定位到原因:注入bean的时候,直接调用了自身,而没有调用自身的代理类。
问题产生的原因,spring循环依赖注入原理:
查问题的时候,找到一篇大佬写的文章,讲述的特别详细:https://blog.csdn.net/lianhuazy167/article/details/66967673,摘抄部分核心文字过来,以让大家更好的理解。
步骤1:A依赖B、C依赖B,B依赖C,并且B实现类的方法上存在@async注解,即B在实例化完成前会生成代理。
步骤2:A开始create,发现B未实例化,于是先cache A。
步骤3:B开始create,发现C未实例化,于是先cache B。
步骤4:C开始create,发现B已实例化,取出cache的B,注入C中,C finish。
(为什么B未实例化完就注入到C中了?that is not fully initialized yet - a consequence of a circular reference,因为存在循环依赖,所以允许先注入。猜测未做是否被代理的检测)
步骤5:生成B的代理类B@108e。
步骤6:B@108e注入到A时,发现B@108e的原始实例B已注入到循环引用的C中,却没有使用B的最终代理类B@108e,所以抛异常。
上述几个步骤,如果大家按顺序仔细推敲一下,就能大概明白问题的所在了,其实总的来说,跟以前碰见的事务注解不生效的问题差不多,都是代理没有被正确注入导致,讲真,我感觉提示“多个bean注入失败”更贴近。。。
解决方案:
1、重新建个类,将用@Async注解的方法都移出去放在此类中,再将新建的类注入进去;
2、在@Autowired注解上加上@Lazy懒加载注解;
上述两个方法二选一!!!
看完文章,有任何疑问,请加入群聊一起交流!!!
很赞哦! ()
相关文章
- JPA报错“No identifier specified for entity”的原因
- springboot整合jpa启动报错'hibernate.dialect' not set
- springboot使用jackson处理时间碰到的两个坑
- Linux不使用tomcat搭建springboot服务图文教程
- springboot项目提示“Failed to determine a suitable driver class”
- springboot打war包,部署到外部tomcat
- springboot项目在mac下启动特别慢
- 使用idea搭建springboot项目图文教程
- Spring Boot配置Druid数据源和使用教程
- springboot连接mysql报错“java.lang.IllegalArgumentException: HOUR_OF_DAY: 2 -> 3”
标签云
猜你喜欢
- IntelliJ IDEA 2019.2已经可以利用补丁永久破解激活了
- IntelliJ IDEA 2019.3利用补丁永久破解激活教程
- IntelliJ IDEA高版本最灵活的永久破解激活方法(含插件激活,时长你说了算)
- Jetbrains全家桶基于ja-netfilter的最新破解激活详细图文教程
- IntelliJ IDEA 2022.1永久破解激活教程(亲测可用,持续更新)
- 分享几个正版 IntelliJ IDEA 激活码(破解码、注册码),亲测可用,持续更新
- ja-netfilter到底需不需要mymap,2021.3.2版本激活失效?
- 如何激活idea2022.1及以上版本中的插件(亲测可用)
- 【史上最全】IntelliJ IDEA最新2022.1版本安装和激活视频教学(含插件)
- IntelliJ IDEA 2022.2 版本最新2099年永久激活方法,亲测可用,也可以开启新UI了。
站点信息
- 网站程序:spring + freemarker
- 主题模板:《今夕何夕》
- 文章统计:篇文章
- 标签管理:标签云
- 微信公众号:扫描二维码,关注我们