构造器的循环依赖,可以在构造函数中使用@Lazy注解延迟加载。在注入依赖时,先注入代理对象,当首次使用时再创建对象完成注入
属性的循环依赖主要是通过3个map来解决的
构造器的循环依赖
- @Component
- public class ConstructorA {
- private ConstructorB constructorB;
- @Autowired
- public ConstructorA(ConstructorB constructorB) {
- this.constructorB = constructorB;
- }
- }
- @Component
- public class ConstructorB {
- private ConstructorA constructorA;
- @Autowired
- public ConstructorB(ConstructorA constructorA) {
- this.constructorA = constructorA;
- }
- }
- @Configuration
- @ComponentScan("com.javashitang.dependency.constructor")
- public class ConstructorConfig {
- }
- public class ConstructorMain {
- public static void main(String[] args) {
- AnnotationConfigApplicationContext context =
- new AnnotationConfigApplicationContext(ConstructorConfig.class);
- System.out.println(context.getBean(ConstructorA.class));
- System.out.println(context.getBean(ConstructorB.class));
- }
- }
运行ConstructorMain的main方法的时候会在第一行就报异常,说明Spring没办法初始化所有的Bean,即上面这种形式的循环依赖Spring无法解决。
我们可以在ConstructorA或者ConstructorB构造函数的参数上加上@Lazy注解就可以解决
- @Autowired
- public ConstructorB(@Lazy ConstructorA constructorA) {
- this.constructorA = constructorA;
- }
因为我们主要关注属性的循环依赖,构造器的循环依赖就不做过多分析了
属性的循环依赖
先演示一下什么是属性的循环依赖
- @Component
- public class FieldA {
- @Autowired
- private FieldB fieldB;
- }
- @Component
- public class FieldB {
- @Autowired
- private FieldA fieldA;
- }
- @Configuration
- @ComponentScan("com.javashitang.dependency.field")
- public class FieldConfig {
- }
- public class FieldMain {
- public static void main(String[] args) {
- AnnotationConfigApplicationContext context =
- new AnnotationConfigApplicationContext(FieldConfig.class);
- // com.javashitang.dependency.field.FieldA@3aa9e816
- System.out.println(context.getBean(FieldA.class));
- // com.javashitang.dependency.field.FieldB@17d99928
- System.out.println(context.getBean(FieldB.class));
- }
- }
Spring容器正常启动,能获取到FieldA和FieldB这2个Bean