国产成人精品久久免费动漫-国产成人精品天堂-国产成人精品区在线观看-国产成人精品日本-a级毛片无码免费真人-a级毛片毛片免费观看久潮喷

您的位置:首頁技術(shù)文章
文章詳情頁

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

瀏覽:7日期:2023-05-20 16:50:26

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

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

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

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

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

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

@Componentpublic 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.解決方法

處理這種問題目前有如下幾種常見方式。

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

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

4.2 使用注解 @Lazy

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

@Componentpublic 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)依賴最終被使用時(shí)才進(jìn)行注入。對(duì)前文的樣例代碼少做修改,來觀察測(cè)試效果。

@Componentpublic class CircularDependencyA { private CircularDependencyB circB; @Autowired public void setCircB(CircularDependencyB circB) { this.circB = circB; } public CircularDependencyB getCircB() { return circB; }}

@Componentpublic 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

@Componentpublic class CircularDependencyA { @Autowired private CircularDependencyB circB; @PostConstruct public void init() { circB.setCircA(this); } public CircularDependencyB getCircB() { return circB; }}

@Componentpublic 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

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

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

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

標(biāo)簽: Spring
相關(guān)文章:
主站蜘蛛池模板: 扒开双腿猛进入喷水免费视频 | 欧美一级一一特黄 | 蜜臀91精品国产高清在线观看 | 99热在线观看 | 国产高清在线精品二区一 | 国产午夜久久影院 | 成人在免费观看视频国产 | 欧美激情免费a视频 | 在线欧美 | 成人午夜在线观看国产 | 国产在线精品观看 | 国产人成精品综合欧美成人 | 久久久国产精品免费 | 99在线播放视频 | 久久久久亚洲精品影视 | 国产亚洲人成网站在线观看不卡 | 亚洲在线播放视频 | 男人的天堂精品国产一区 | 美国一级片免费看 | 色偷偷88欧美精品久久久 | 日本一级高清不卡视频在线 | 最新理论三级中文在线观看 | 毛片免费在线观看 | 欧美一区二区高清 | 美毛片| 成年女人免费观看 | 在线视频一区二区三区三区不卡 | 国产一久久香蕉国产线看观看 | 久草在线视频免费看 | 久久久精品国产 | 92手机看片福利永久国产 | 综合久久99久久99播放 | 欧美午夜网 | 国产精品不卡无毒在线观看 | 欧美一区二区在线观看免费网站 | 宫女淫春3在线观 | 日韩欧美亚洲视频 | 中日韩一区二区三区 | 免费精品99久久国产综合精品 | 精品国产理论在线观看不卡 | 一级毛片在线免费视频 |