欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

基于SpringBoot構(gòu)造器注入循環(huán)依賴(lài)及解決方式

 更新時(shí)間:2020年04月26日 16:23:10   作者:FserSuN  
這篇文章主要介紹了基于SpringBoot構(gòu)造器注入循環(huán)依賴(lài)及解決方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧

1. 循環(huán)依賴(lài)是什么?

Bean A 依賴(lài) B,Bean B 依賴(lài) A這種情況下出現(xiàn)循環(huán)依賴(lài)。

Bean A → Bean B → Bean A

更復(fù)雜的間接依賴(lài)造成的循環(huán)依賴(lài)如下。

Bean A → Bean B → Bean C → Bean D → Bean E → Bean A

2. 循環(huán)依賴(lài)會(huì)產(chǎn)生什么結(jié)果?

當(dāng)Spring正在加載所有Bean時(shí),Spring嘗試以能正常創(chuàng)建Bean的順序去創(chuàng)建Bean。

例如,有如下依賴(lài):

Bean A → Bean B → Bean C

Spring先創(chuàng)建beanC,接著創(chuàng)建bean B(將C注入B中),最后創(chuàng)建bean A(將B注入A中)。

但當(dāng)存在循環(huán)依賴(lài)時(shí),Spring將無(wú)法決定先創(chuàng)建哪個(gè)bean。這種情況下,Spring將產(chǎn)生異常BeanCurrentlyInCreationException。

當(dāng)使用構(gòu)造器注入時(shí)經(jīng)常會(huì)發(fā)生循環(huán)依賴(lài)問(wèn)題。如果使用其它類(lèi)型的注入方式能夠避免這種問(wèn)題。

3. 構(gòu)造器注入循環(huán)依賴(lài)實(shí)例

首先定義兩個(gè)相互通過(guò)構(gòu)造器注入依賴(lài)的bean。

@Component
public class CircularDependencyA {
 
 private CircularDependencyB circB;
 
 @Autowired
 public CircularDependencyA(CircularDependencyB circB) {
  this.circB = circB;
 }
}
@Component
public class CircularDependencyB {
 
 private CircularDependencyA circA;
 
 @Autowired
 public CircularDependencyB(CircularDependencyA circA) {
  this.circA = circA;
 }
}
@Configuration
@ComponentScan(basePackages = { "com.baeldung.circulardependency" })
public class TestConfig {
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { TestConfig.class })
public class CircularDependencyTest {
 
 @Test
 public void givenCircularDependency_whenConstructorInjection_thenItFails() {
  // Empty test; we just want the context to load
 }
}

運(yùn)行方法givenCircularDependency_whenConstructorInjection_thenItFails將會(huì)產(chǎn)生異常:

BeanCurrentlyInCreationException: Error creating bean with name ‘circularDependencyA': Requested bean is currently in creation: Is there an unresolvable circular reference?

4.解決方法

處理這種問(wèn)題目前有如下幾種常見(jiàn)方式。

4.1 重新設(shè)計(jì)

重新設(shè)計(jì)結(jié)構(gòu),消除循環(huán)依賴(lài)。

4.2 使用注解 @Lazy

一種最簡(jiǎn)單的消除循環(huán)依賴(lài)的方式是通過(guò)延遲加載。在注入依賴(lài)時(shí),先注入代理對(duì)象,當(dāng)首次使用時(shí)再創(chuàng)建對(duì)象完成注入。

@Component
public class CircularDependencyA {
 
 private CircularDependencyB circB;
 
 @Autowired
 public CircularDependencyA(@Lazy CircularDependencyB circB) {
  this.circB = circB;
 }
}

使用@Lazy后,運(yùn)行代碼,可以看到異常消除。

4.3 使用Setter/Field注入

Spring文檔建議的一種方式是使用setter注入。當(dāng)依賴(lài)最終被使用時(shí)才進(jìn)行注入。對(duì)前文的樣例代碼少做修改,來(lái)觀察測(cè)試效果。

@Component
public class CircularDependencyA {
 
 private CircularDependencyB circB;
 
 @Autowired
 public void setCircB(CircularDependencyB circB) {
  this.circB = circB;
 }
 
 public CircularDependencyB getCircB() {
  return circB;
 }
}
@Component
public class CircularDependencyB {
 
 private CircularDependencyA circA;
 
 private String message = "Hi!";
 
 @Autowired
 public void setCircA(CircularDependencyA circA) {
  this.circA = circA;
 }
 
 public String getMessage() {
  return message;
 }
}
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { TestConfig.class })
public class CircularDependencyTest {
 
 @Autowired
 ApplicationContext context;
 
 @Bean
 public CircularDependencyA getCircularDependencyA() {
  return new CircularDependencyA();
 }
 
 @Bean
 public CircularDependencyB getCircularDependencyB() {
  return new CircularDependencyB();
 }
 
 @Test
 public void givenCircularDependency_whenSetterInjection_thenItWorks() {
  CircularDependencyA circA = context.getBean(CircularDependencyA.class);

  Assert.assertEquals("Hi!", circA.getCircB().getMessage());
 }
}

4.4 使用@PostConstruct

@Component
public class CircularDependencyA {
 
 @Autowired
 private CircularDependencyB circB;
 
 @PostConstruct
 public void init() {
  circB.setCircA(this);
 }
 
 public CircularDependencyB getCircB() {
  return circB;
 }
}
@Component
public class CircularDependencyB {
 
 private CircularDependencyA circA;
  
 private String message = "Hi!";
 
 public void setCircA(CircularDependencyA circA) {
  this.circA = circA;
 }
  
 public String getMessage() {
  return message;
 }

4.5 實(shí)現(xiàn)ApplicationContextAware與InitializingBean

@Component
public class CircularDependencyA implements ApplicationContextAware, InitializingBean {
 
 private CircularDependencyB circB;
 
 private ApplicationContext context;
 
 public CircularDependencyB getCircB() {
  return circB;
 }
 
 @Override
 public void afterPropertiesSet() throws Exception {
  circB = context.getBean(CircularDependencyB.class);
 }
 
 @Override
 public void setApplicationContext(final ApplicationContext ctx) throws BeansException {
  context = ctx;
 }
}
@Component
public class CircularDependencyB {
 
 private CircularDependencyA circA;
 
 private String message = "Hi!";
 
 @Autowired
 public void setCircA(CircularDependencyA circA) {
  this.circA = circA;
 }
 
 public String getMessage() {
  return message;
 }
}

5.總結(jié)

處理循環(huán)依賴(lài)有多種方式。首先考慮是否能夠通過(guò)重新設(shè)計(jì)依賴(lài)來(lái)避免循環(huán)依賴(lài)。如果確實(shí)需要循環(huán)依賴(lài),那么可以通過(guò)前文提到的方式來(lái)處理。優(yōu)先建議使用setter注入來(lái)解決。

以上這篇基于SpringBoot構(gòu)造器注入循環(huán)依賴(lài)及解決方式就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 詳解Python爬取并下載《電影天堂》3千多部電影

    詳解Python爬取并下載《電影天堂》3千多部電影

    這篇文章主要介紹了Python爬取并下載《電影天堂》3千多部電影,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • Python中函數(shù)帶括號(hào)和不帶括號(hào)的區(qū)別及說(shuō)明

    Python中函數(shù)帶括號(hào)和不帶括號(hào)的區(qū)別及說(shuō)明

    這篇文章主要介紹了Python中函數(shù)帶括號(hào)和不帶括號(hào)的區(qū)別及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-11-11
  • Python操作Elasticsearch處理timeout超時(shí)

    Python操作Elasticsearch處理timeout超時(shí)

    這篇文章主要介紹了Python操作Elasticsearch處理timeout超時(shí),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-07-07
  • 利用Python的Twisted框架實(shí)現(xiàn)webshell密碼掃描器的教程

    利用Python的Twisted框架實(shí)現(xiàn)webshell密碼掃描器的教程

    這篇文章主要介紹了利用Python的Twisted框架實(shí)現(xiàn)webshell密碼掃描器的教程,用到了Twisted框架的異步通信機(jī)制,需要的朋友可以參考下
    2015-04-04
  • python繪制BA無(wú)標(biāo)度網(wǎng)絡(luò)示例代碼

    python繪制BA無(wú)標(biāo)度網(wǎng)絡(luò)示例代碼

    今天小編就為大家分享一篇python繪制BA無(wú)標(biāo)度網(wǎng)絡(luò)示例代碼,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2019-11-11
  • python實(shí)現(xiàn)Scrapy爬取網(wǎng)易新聞

    python實(shí)現(xiàn)Scrapy爬取網(wǎng)易新聞

    這篇文章主要介紹了python實(shí)現(xiàn)Scrapy爬取網(wǎng)易新聞,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • Python AutoCAD 系統(tǒng)設(shè)置的實(shí)現(xiàn)方法

    Python AutoCAD 系統(tǒng)設(shè)置的實(shí)現(xiàn)方法

    這篇文章主要介紹了Python AutoCAD 系統(tǒng)設(shè)置的實(shí)現(xiàn)方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04
  • Anaconda配置pytorch-gpu虛擬環(huán)境的圖文教程

    Anaconda配置pytorch-gpu虛擬環(huán)境的圖文教程

    這篇文章主要介紹了Anaconda配置pytorch-gpu虛擬環(huán)境步驟整理,本文分步驟通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-04-04
  • Python 中面向接口編程詳情

    Python 中面向接口編程詳情

    這篇文章主要介紹了Python 中面向接口編程詳情,Python 中的接口與大多數(shù)其它語(yǔ)言的處理方式不同,它們的設(shè)計(jì)復(fù)雜性也不同,關(guān)于Python 接口編程的介紹,需要的小伙伴可以參考下面文章內(nèi)容
    2022-05-05
  • Python爬蟲(chóng)之BeautifulSoup的基本使用教程

    Python爬蟲(chóng)之BeautifulSoup的基本使用教程

    Beautiful Soup提供一些簡(jiǎn)單的、python式的函數(shù)用來(lái)處理導(dǎo)航、搜索、修改分析樹(shù)等功,下面這篇文章主要給大家介紹了關(guān)于Python爬蟲(chóng)之BeautifulSoup的基本使用教程,需要的朋友可以參考下
    2022-03-03

最新評(píng)論