一、Spring不能解决的三种循环依赖问题
1. 构造器注入类型循环依赖
1)代码示例
@Component
class A1 {
private B1 b1;
public A1(B1 b1) {
this.b1 = b1;
}
}
@Component
class B1 {
private A1 a1;
public B1(A1 a1) {
this.a1 = a1;
}
}
2)错误信息
![在这里插入图片描述](https://img-blog.csdnimg.cn/b91337faac3d4618a596caca37ead130.png)
![在这里插入图片描述](https://img-blog.csdnimg.cn/84006f926c694524939899ba5e597912.png)
2. @Async类型循环依赖
1)代码示例
@Component
class A2 {
@Resource
private B2 b2;
@Async
public void hello() {
System.out.println("hello I'm a2! ");
}
}
@Component
class B2 {
@Resource
@Lazy
private A2 a2;
public void hello() {
System.out.println("hello I'm b2! ");
}
}
2)错误信息
![在这里插入图片描述](https://img-blog.csdnimg.cn/23e5905ae9884d1c95019ea53230b498.png)
3. prototype类型循环依赖
1)代码示例
@Component
@Scope("prototype")
class A3 {
@Resource
private B3 b3;
}
@Component
@Scope("prototype")
class B3 {
@Resource
private A3 a3;
}
2)错误信息
![在这里插入图片描述](https://img-blog.csdnimg.cn/99e05ac1cdfd4a6d813b8742769ef9a9.png)
二、解决方案
在需要循环注入的属性上加上@Lazy 来解决循环依赖问题
三、单元测试
package com.example.demo5;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
/**
* @Author lcb
* @Date 2023/03/14
**/
@SpringBootTest
public class CirculateDependencyTest {
@Resource
private A1 a1;
@Test
void constructorTest() {
}
@Resource
private B2 b2;
@Test
void asyncTest() {
}
@Resource
private A3 a3;
@Test
void prototypeTest() {
}
}
//1、构造器注入问题
@Component
class A1 {
private B1 b1;
@Lazy
public A1(B1 b1) {
this.b1 = b1;
}
}
@Component
class B1 {
private A1 a1;
public B1(A1 a1) {
this.a1 = a1;
}
}
//2、@Async
@Component
class A2 {
@Resource
private B2 b2;
@Async
public void hello() {
System.out.println("hello I'm a2! ");
}
}
@Component
class B2 {
@Resource
@Lazy
private A2 a2;
public void hello() {
System.out.println("hello I'm b2! ");
}
}
//3、prototype
@Component
@Scope("prototype")
class A3 {
@Resource
@Lazy
private B3 b3;
}
@Component
@Scope("prototype")
class B3 {
@Resource
private A3 a3;
}