帮助你更好的理解Spring循环依赖

网上关于Spring循环依赖的博客太多了,有很多都分析的很深入,写的很用心,甚至还画了时序图、流程图帮助读者理解,我看了后,感觉自己是懂了,但是闭上眼睛,总觉得还没有完全理解,总觉得还有一两个坎过不去,对我这种有点笨的人来说,真的好难。当时,我就在想,如果哪一天,我理解了Spring循环依赖,一定要用自己的方式写篇博客,帮助大家更好的理解,等我理解后,一直在构思,到底怎么应该写,才能更通俗易懂,就在前几天,我想通了,这么写应该更通俗易懂。在写本篇博客之前,我翻阅了好多关于Spring循环依赖的博客,网上应该还没有像我这样讲解的,现在就让我们开始把。

什么是循环依赖

一言以蔽之:两者相互依赖。

在开发中,可能经常出现这种情况,只是我们平时并没有注意到原来我们写的两个类、甚至多个类相互依赖了,为什么注意不到呢?当然是因为没有报错,而且一点问题都木有,如果报错了,或者产生了问题,我们还会注意不到吗?这一切都是Spring的功劳,它在后面默默的为我们解决了循环依赖的问题。

如下所示:

@Configuration @ComponentScan public class AppConfig { } @Service public class AuthorService { @Autowired BookService bookService; } @Service public class BookService { @Autowired AuthorService authorService; } public class Main { public static void main(String[] args) { ApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(AppConfig.class); BookService bookService = (BookService) annotationConfigApplicationContext.getBean("bookService"); System.out.println(bookService.authorService); AuthorService authorService = (AuthorService) annotationConfigApplicationContext.getBean("authorService"); System.out.println(authorService.bookService); } }

运行结果:

com.codebear.springcycle.AuthorService@63376bed com.codebear.springcycle.BookService@4145bad8

可以看到BookService中需要AuthorService,AuthorService中需要BookService,类似于这样的就叫循环依赖,但是神奇的是竟然一点问题没有。

当然有些小伙伴可能get不到它的神奇之处,至于它的神奇之处在哪里,我们放到后面再说。

任何循环依赖,Spring都能解决吗

不行。

如果是原型 bean的循环依赖,Spring无法解决:

@Service @Scope(BeanDefinition.SCOPE_PROTOTYPE) public class BookService { @Autowired AuthorService authorService; } @Service @Scope(BeanDefinition.SCOPE_PROTOTYPE) public class AuthorService { @Autowired BookService bookService; }

启动后,令人恐惧的红色字体在控制台出现了:

如果是构造参数注入的循环依赖,Spring无法解决:

@Service public class AuthorService { BookService bookService; public AuthorService(BookService bookService) { this.bookService = bookService; } } @Service public class BookService { AuthorService authorService; public BookService(AuthorService authorService) { this.authorService = authorService; } }

还是讨厌的红色字体:

循环依赖可以关闭吗

可以,Spring提供了这个功能,我们需要这么写:

public class Main { public static void main(String[] args) { AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(); applicationContext.setAllowCircularReferences(false); applicationContext.register(AppConfig.class); applicationContext.refresh(); } }

再次运行,就报错了:

需要注意的是,我们不能这么写:

AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(AppConfig.class); applicationContext.setAllowCircularReferences(false);

如果你这么写,程序执行完第一行代码,整个Spring容器已经初始化完成了,你再设置不允许循环依赖,也于事无补了。

可以循环依赖的神奇之处在哪

有很多小伙伴可能并不觉得可以循环依赖有多么神奇,那是因为不知道矛盾点在哪,接下来就来说说这个问题:
当beanA,beanB循环依赖:

创建beanA,发现依赖beanB;

创建beanB,发现依赖beanA;

创建beanA,发现依赖beanB;

创建beanB,发现依赖beanA。
...
好了,死循环了。

循环依赖的矛盾点就在于要创建beanA,它需要beanB,而创建beanB,又需要beanA,然后两个bean都创建不出来。

如何简单的解决循环依赖

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwzxsd.html