Spring 使用@Async出现循环依赖Bean报错的解决方案
初现端倪
Caused by:org.springframework.beans.factory.BeanCurrentlyInCreationException: Errorcreating bean with name 'asyncUpdate': Bean with name 'asyncUpdate' has beeninjected into other beans [dealerService,userService] in its raw version aspart of a circular reference, but has eventually been wrapped. This means thatsaid other beans do not use the final version of the bean. This is often theresult of over-eager type matching - consider using 'getBeanNamesOfType' withthe 'allowEagerInit' flag turned off, for example.
以上这一长串大概的意思就是说,'asyncUpdate' bean已经注入了一个版本,程序中出现了循环依赖的可能性。
就如:在创建A类时,构造器需要B类,那将去创建B,在创建B类时又发现需要C类,则又去创建C,最终在创建C时发现又需要A,从而形成一个环,没办法创建。
分析问题
首先来看看这里的AsyncUpdate类是用来做什么的:
@Component
@EnableAsync
public classAsyncUpdate {
@Autowired
private DealerMemberMapper dealerMemberMapper;
@Autowired
private UserService userService;
@Autowired
private GoodsSubscribeService goodsSubscribeService;
/**
*异步更新
*/
@Async
public void updateDealerAsync(Dealer dealer, String mobilephone, Integer type) throwsException {
//篇幅有限就不贴代码
}
}
@Async注解:表示当前是一个异步方法。
@Component:表示把普通pojo实例化到spring容器中,相当于配置文件中的。
@EnableAsync注解:表示开启异步线程。
@Service
public classDealerService {
@Autowired
private DealerMapper dealerMapper;
@Autowired
private UserService userService;
@Autowired
private AsyncUpdate asyncUpdate;
//一些代码
}
通过以上两段程序能够得到,问题出现的原因:简单的讲就是在启动程序的时候,Spring已经对DealerService里的asyncUpdate、userService加载完成,当准备创建AsyncUpdate类的时候发现使用了@Async注解,即spring又需将该Bean代理一次,然后Spring发现该Bean已经被其他对象注入,这里就是问题的关键所在了。
即:在创建A类时,构造器需要B类,那将去创建B,在创建B类时又发现需要C类,则又去创建C,最终在创建C时发现又需要A,从而形成一个环,没办法创建
解决方案
大量查找解决方案后发现解决方案有三:
1.使用 @Lazy 或者 @ComponentScan(lazyInit = true) 来解决该问题,经过我实验,@Lazy必须和@Autowired联合使用才能生效,单纯在类上添加 @Lazy 并无意义。
@Autowired
@Lazy
private AsyncUpdate asyncUpdate;
- 使用基于 Setter 的注入
@Component
public classDealerService {
private AsyncUpdate a;
public void setA(AsyncUpdate a) {
this.a = a;
}
}
@Component
public classAsyncUpdate {
private DealerService ds;
public void setDs(DealerService ds) {
this.ds = ds;
}
}
3.使用@Autowired注解防止循环注入,如:
@Component
public classDealerService {
@Autowired
private AsyncUpdate a;
}
@Component
public classAsyncUpdate {
private DealerService ds;
@Autowired
public void foo(DealerService ds) {
this.ds= ds;
}
}
注:当@Autowired 对方法或构造函数进行标注时,表示如果构造函数有两个入参,分别是 bean1 和bean2,@Autowired 将分别寻找和它们类型匹配的 Bean,将它们作为 baanService (Bean1 bean1 ,Bean2 bean2) 的入参来创建baanService Bean。
Spring 使用@Async出现循环依赖Bean报错的解决方案的更多相关文章
- spring: 我是如何解决循环依赖的?
1.由同事抛的一个问题开始 最近项目组的一个同事遇到了一个问题,问我的意见,一下子引起的我的兴趣,因为这个问题我也是第一次遇到.平时自认为对spring循环依赖问题还是比较了解的,直到遇到这个和后面的 ...
- Spring 是如何解决循环依赖的?
前言 相信很多小伙伴在工作中都会遇到循环依赖,不过大多数它是这样显示的: 还会提示这么一句: Requested bean is currently in creation: Is there an ...
- [跟我学spring学习笔记][DI循环依赖]
循环依赖 什么是循环依赖? 循环依赖就是循环引用,就是两个或多个Bean相互之间的持有对方. Spring容器循环依赖包括构造器循环依赖和setter循环依赖,那Spring容器如何解决循环依赖呢? ...
- Spring.getBean()流程和循环依赖的解决
getBean流程介绍(以单例的Bean流程为准) getBean(beanName) 从BeanFactory中获取Bean的实例对象,真正获取的逻辑由doGetBean实现. doGetBean( ...
- Spring是如何解决循环依赖的
前言 在面试的时候这两年有一个非常高频的关于spring的问题,那就是spring是如何解决循环依赖的.这个问题听着就是轻描淡写的一句话,其实考察的内容还是非常多的,主要还是考察的应聘者有没有研究过s ...
- 听说你还不知道Spring是如何解决循环依赖问题的?
Spring如何解决的循环依赖,是近两年流行起来的一道Java面试题. 其实笔者本人对这类框架源码题还是持一定的怀疑态度的. 如果笔者作为面试官,可能会问一些诸如"如果注入的属性为null, ...
- Spring 是怎么处理循环依赖的?
Java语法中的循环依赖 首先看一个使用构造函数的循环依赖,如下: public class ObjectA { private ObjectB b; public ObjectA(ObjectB b ...
- SpringBoot导入jsp依赖始终报错
先粘出我自己的pom代码: <?xml version="1.0" encoding="UTF-8"?> <project xmlns=&qu ...
- 目标平台、活动平台 配置,出现未能加载文件或程序集“xxx”或它的某一个依赖项报错
今天在做动态加载程序集的时候,发现明明程序集存在的情况下,还是依然报“未能加载文件或程序集“xxx”或它的某一个依赖项报错”的错误,排除了程序和配置的错误后,怀疑是否是环境的问题,于是百度加msdn后 ...
随机推荐
- python-django之cookie及session
Cookie Cookie的由来 Http协议是无状态的 无状态的意思是每次都是独立的请求存在,它的执行情况和结果与前面的请求和后面的请求都无直接关系,它不会受到前面的请求响应情况直接影响,也不会直接 ...
- Spring clound 微服务--理解篇
定义:微服务就是一些协调工作的小而自治的服务 优点: 异构性:不同微服务可以使用不同的语言实现, 后端数据库也可以根据自身业务定义服务. 弹性: 一个组件不可用,不会导致级联故障.一个系统出了问题,不 ...
- WebSocket 网页聊天室
先给大家开一个原始的websocket的连接使用范例 <?php /* * recv是从套接口接收数据,也就是拿过来,但是不知道是什么 * read是读取拿过来的数据,就是要知道recv过来的是 ...
- Java开发中的23种设计模式详解(3)行为型
本章是关于设计模式的最后一讲,会讲到第三种设计模式--行为型模式,共11种:策略模式.模板方法模式.观察者模式.迭代子模式.责任链模式.命令模式.备忘录模式.状态模式.访问者模式.中介者模式.解释器模 ...
- nginx的原理
Nginx会按需同时运行多个进程:一个主进程(master)和几个工作进程(worker),配置了缓存时还会有缓存加载器进程 (cache loader)和缓存管理器进程(cache manager) ...
- Java8 LocalDate操作时间和日期的API
时间项目中的涉及到的时间处理非常多,犹豫SimpleDateFormat的不安全性以及Calendar等类在计算时比较复杂, 往往我们都会使用工具类来封装较多的日期处理函数, 但是JDK8中新增了操作 ...
- 【知识强化】第四章 网络层 4.4 IPv4
这节课我们来学习一个非常重要的概念,就是IPv4地址,其实也是我们常用的IP地址. 首先我们来了解一下,为什么会有IP地址的出现以及它是做什么用的.假如说在很多年前我遇到一个女生非常的漂亮,等了十年之 ...
- Ubuntu14.04搭建Boa服务
1. 下载 boa 源码 : https://sourceforge.net/projects/boa/ 版本:boa-0.94.13.tar.gz 2. 在Ubuntu 下解压进入 [boa-0.0 ...
- 2019HDU多校训练第三场 Planting Trees 暴力 + 单调队列优化
题意:有一个n * n的网格,每个网格中间有一颗树,你知道每棵树的高,你可以选择一个矩形区域把里面的树都围起来,但是矩形区域里面任意两棵树的高度差的绝对值不超过m,问这个矩形的最大面积是多少? 思路: ...
- python3.x 匿名函数lambda_扩展sort
#匿名函数lambda 参数: 表达式关键字 lambda 说明它是一个匿名函数,冒号 : 前面的变量是该匿名函数的参数,冒号后面是函数的返回值,注意这里不需使用 return 关键字. ambda只 ...