最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

SpringBoot構(gòu)造器注入循環(huán)依賴及解決方案

 更新時(shí)間:2024年03月27日 11:35:22   作者:不懂原理的程序員.  
這篇文章主要介紹了SpringBoot構(gòu)造器注入循環(huán)依賴及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

SpringBoot構(gòu)造器注入循環(huán)依賴及解決

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

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

Bean A → Bean B → Bean A

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

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

(解釋一下,三個(gè)以上其實(shí)和兩個(gè)是一樣的,多加幾個(gè)@lazy就可以了,等到后面bean創(chuàng)建成功再創(chuàng)建)

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

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

例如,有如下依賴:

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)依賴時(shí),Spring將無(wú)法決定先創(chuàng)建哪個(gè)bean。這種情況下,Spring將產(chǎn)生異常BeanCurrentlyInCreationException。

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

簡(jiǎn)單構(gòu)造器注入循環(huán)依賴實(shí)例

項(xiàng)目結(jié)構(gòu)

如下:

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

/**
 * @Author: lixs
 * @Date: 2021/4/6
 * @Description: 循環(huán)依賴類A
 */
@Component
public class CircularDependencyA {


    private CircularDependencyB circB;

    @Autowired
    public CircularDependencyA(@Lazy CircularDependencyB circB) {
        this.circB = circB;
    }
}
/**
 1. @Author: lixs
 2. @Date: 2021/4/6
 3. @Description: 循環(huán)依賴類B
 */
@Component
public class CircularDependencyB {

    private CircularDependencyA circA;

    @Autowired
    public CircularDependencyB(@Lazy CircularDependencyA circA) {
        this.circA= circA;
    }
}

2.創(chuàng)建配置類

/**
 1. @Author: lixs
 2. @Date: 2021/4/6
 3. @Description: 配置類
 */
@Configuration
@ComponentScan(basePackages = { "com.li.springboot.bean" })
public class TestConfig {
}

3.創(chuàng)建測(cè)試類

@SpringBootTest
@ContextConfiguration(classes = {TestConfig.class})
class ApplicationTests {

    @Test
    public void givenCircularDependency_whenConstructorInjection_thenItFails() {
        // Empty test; we just want the context to load
    }
}

正常運(yùn)行結(jié)果:

上面就是報(bào)的是循環(huán) 依賴無(wú)法創(chuàng)建bean錯(cuò)誤!

解決方案

1.重新設(shè)計(jì)

重新設(shè)計(jì)結(jié)構(gòu),不用這種方式去創(chuàng)建bean。

2.使用注解 @Lazy

一種最簡(jiǎn)單的消除循環(huán)依賴的方式是通過(guò)延遲加載。

在注入依賴時(shí),先注入代理對(duì)象,當(dāng)首次使用時(shí)再創(chuàng)建對(duì)象完成注入。

/**
 * @Author: lixs
 * @Date: 2021/4/6
 * @Description: 循環(huán)依賴類A
 */
@Component
public class CircularDependencyA {

    private CircularDependencyB circB;

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

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

3.使用Setter/Field注入

Spring文檔建議的一種方式是使用setter注入。當(dāng)依賴最終被使用時(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;
    }
}

測(cè)試類

@SpringBootTest
@ContextConfiguration(classes = {TestConfig.class})
class ApplicationTests {

     @Autowired
    ApplicationContext context;    //spring容器對(duì)象
 
    @Bean
    public CircularDependencyA getCircularDependencyA() {
        return new CircularDependencyA();
    }
 
    @Bean
    public CircularDependencyB getCircularDependencyB() {
        return new CircularDependencyB();
    }
 
    @Test
    public void testCircularDependency() {
    	//拿到bean對(duì)象
        CircularDependencyA circA = context.getBean(CircularDependencyA.class);
        //獲取屬性值
        String result=circA.getCircB().getMessage();
        System.out.println(result);
    }

4.使用@PostConstruct

@PostContruct是spring框架的注解,在方法上加該注解會(huì)在項(xiàng)目啟動(dòng)的時(shí)候執(zhí)行該方法,也可以理解為在spring容器初始化的時(shí)候執(zhí)行該方法。

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

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

(1)如果某個(gè)類實(shí)現(xiàn)了ApplicationContextAware接口,會(huì)在類初始化完成后調(diào)用setApplicationContext()方法進(jìn)行操作

(2)如果某個(gè)類實(shí)現(xiàn)了InitializingBean接口,會(huì)在類初始化完成后,并在setApplicationContext()方法執(zhí)行完畢后,調(diào)用afterPropertiesSet()方法進(jìn)行操作

@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;
    }
}

總結(jié)

處理循環(huán)依賴有多種方式。

首先考慮是否能夠通過(guò)重新設(shè)計(jì)依賴來(lái)避免循環(huán)依賴。

如果確實(shí)需要循環(huán)依賴,那么可以通過(guò)前文提到的方式來(lái)處理。

優(yōu)先建議使用setter注入來(lái)解決。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java NIO 文件通道 FileChannel 用法及原理

    Java NIO 文件通道 FileChannel 用法及原理

    這篇文章主要介紹了Java NIO 文件通道 FileChannel 用法和原理,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-01-01
  • spring使用redis操作key-value的示例代碼

    spring使用redis操作key-value的示例代碼

    這篇文章主要介紹了spring使用redis操作key-value的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-03-03
  • java集合與數(shù)組的相同點(diǎn)和不同點(diǎn)

    java集合與數(shù)組的相同點(diǎn)和不同點(diǎn)

    今天小編就為大家分享一篇關(guān)于java集合與數(shù)組的相同點(diǎn)和不同點(diǎn),小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧
    2019-04-04
  • 華為技術(shù)專家講解JVM內(nèi)存模型(收藏)

    華為技術(shù)專家講解JVM內(nèi)存模型(收藏)

    這篇文章主要介紹了華為技術(shù)專家講解JVM內(nèi)存模型(收藏)的相關(guān)知識(shí),本文給大家介紹的非常詳細(xì),具有一定的收藏借鑒價(jià)值,需要的朋友可以參考下
    2021-05-05
  • 測(cè)量Java對(duì)象所占內(nèi)存大小方式

    測(cè)量Java對(duì)象所占內(nèi)存大小方式

    這篇文章主要介紹了測(cè)量Java對(duì)象所占內(nèi)存大小方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • Java 客戶端操作 FastDFS 實(shí)現(xiàn)文件上傳下載替換刪除功能

    Java 客戶端操作 FastDFS 實(shí)現(xiàn)文件上傳下載替換刪除功能

    這篇文章主要介紹了Java 客戶端操作 FastDFS 實(shí)現(xiàn)文件上傳下載替換刪除功能,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-10-10
  • SpringBoot2.0整合tk.mybatis異常解決

    SpringBoot2.0整合tk.mybatis異常解決

    本文主要介紹了SpringBoot2.0整合tk.mybatis異常,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-12-12
  • JavaWeb實(shí)現(xiàn)郵件發(fā)送接收功能

    JavaWeb實(shí)現(xiàn)郵件發(fā)送接收功能

    這篇文章主要為大家詳細(xì)介紹了JavaWeb郵件發(fā)送接收功能的實(shí)現(xiàn),郵件發(fā)送和接收功能是非常常用的功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2015-12-12
  • 詳解如何使用Mybatis的攔截器

    詳解如何使用Mybatis的攔截器

    MyBatis?攔截器是?MyBatis?提供的一個(gè)強(qiáng)大特性,它允許你在?MyBatis?執(zhí)行其核心邏輯的關(guān)鍵節(jié)點(diǎn)插入自定義邏輯,從而改變?MyBatis?的默認(rèn)行為,本文給大家詳細(xì)介紹了如何使用Mybatis的攔截器,需要的朋友可以參考下
    2024-03-03
  • Java實(shí)現(xiàn)日志文件監(jiān)聽(tīng)并讀取相關(guān)數(shù)據(jù)的方法實(shí)踐

    Java實(shí)現(xiàn)日志文件監(jiān)聽(tīng)并讀取相關(guān)數(shù)據(jù)的方法實(shí)踐

    本文主要介紹了Java實(shí)現(xiàn)日志文件監(jiān)聽(tīng)并讀取相關(guān)數(shù)據(jù)的方法實(shí)踐,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-05-05

最新評(píng)論

永州市| 贵港市| 大洼县| 松阳县| 丘北县| 吉木乃县| 安乡县| 花垣县| 石首市| 宝山区| 玛沁县| 右玉县| 通榆县| 德令哈市| 普兰店市| 崇信县| 安阳市| 兴仁县| 呼玛县| 同心县| 四会市| 宜章县| 武义县| 正镶白旗| 武邑县| 仁化县| 凌云县| 平度市| 柳河县| 昔阳县| 丽水市| 玛纳斯县| 泰顺县| 东明县| 青阳县| 云浮市| 新平| 西安市| 康保县| 乌海市| 阜阳市|