首頁 > 軟體

Spring迴圈依賴的解決方案詳解

2022-07-09 14:00:45

簡介

說明

本文用範例介紹如何解決Spring的迴圈依賴問題。

相關網址

Spring迴圈依賴之問題復現詳解

公共程式碼

package com.example.controller;
 
import com.example.tmp.A;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
 
@RestController
public class HelloController {
    @Autowired
    private A a;
 
    @GetMapping("/test1")
    public String test1() {
        return a.getTest();
    }
}

方案1. Feild注入單例(@AutoWired)

程式碼

package com.example.tmp;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
 
@Component
public class A {
    @Autowired
    private B b;
 
    private String name = "Tony";
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public String getTest() {
        return b.getAge().toString() + name;
    }
}
package com.example.tmp;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
 
@Component
public class B {
    @Autowired
    private A a;
 
    private Integer age = 20;
 
    public Integer getAge() {
        return age;
    }
 
    public void setAge(Integer age) {
        this.age = age;
    }
 
}

測試

啟動不報錯。

postman存取:http://localhost:8080/test1

後端結果:不報錯

postman結果: 20Tony

方案2. 構造器注入+@Lazy

延遲載入:在注入依賴時,先注入代理物件,當首次使用時再建立物件完成注入。

程式碼

package com.example.tmp;
 
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
 
@Component
public class A {
    private B b;
 
    public A(@Lazy B b) {
        this.b = b;
    }
 
    private String name = "Tony";
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public String getTest() {
        return b.getAge().toString() + name;
    }
}
package com.example.tmp;
 
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;
 
@Component
public class B {
    private A a;
 
    public B(@Lazy A a) {
        this.a = a;
    }
 
    private Integer age = 20;
 
    public Integer getAge() {
        return age;
    }
 
    public void setAge(Integer age) {
        this.age = age;
    }
 
}

測試

啟動不報錯。

postman存取:http://localhost:8080/test1

後端結果:不報錯

postman結果: 20Tony

方案3. Setter/Field注入單例

程式碼

package com.example.tmp;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
 
@Component
public class A {
    private B b;
 
    private String name = "Tony";
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public String getTest() {
        return b.getAge().toString() + name;
    }
 
    public B getB() {
        return b;
    }
 
    @Autowired
    public void setB(B b) {
        this.b = b;
    }
}
package com.example.tmp;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
 
@Component
public class B {
    private A a;
 
    private Integer age = 20;
 
    public Integer getAge() {
        return age;
    }
 
    public void setAge(Integer age) {
        this.age = age;
    }
 
    public A getA() {
        return a;
    }
 
    @Autowired
    public void setA(A a) {
        this.a = a;
    }
}

測試 

啟動不報錯。

postman存取:http://localhost:8080/test1

後端結果:不報錯

postman結果: 20Tony

方案4. @PostConstruct

程式碼

package com.example.tmp;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
 
import javax.annotation.PostConstruct;
 
@Component
public class A {
    @Autowired
    private B b;
 
    @PostConstruct
    public void init() {
        b.setA(this);
    }
 
    private String name = "Tony";
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public String getTest() {
        return b.getAge().toString() + name;
    }
}
package com.example.tmp;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
 
@Component
public class B {
    @Autowired
    private A a;
 
    private Integer age = 20;
 
    public Integer getAge() {
        return age;
    }
 
    public void setAge(Integer age) {
        this.age = age;
    }
 
    public A getA() {
        return a;
    }
 
    public void setA(A a) {
        this.a = a;
    }
}

測試 

啟動不報錯。

postman存取:http://localhost:8080/test1

後端結果:不報錯

postman結果: 20Tony

方案5. 實現ApplicationContextAware與InitializingBean

程式碼 

package com.example.tmp;
 
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
 
@Component
public class A implements ApplicationContextAware, InitializingBean {
    private B b;
 
    private ApplicationContext context;
 
    private String name = "Tony";
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public String getTest() {
        return b.getAge().toString() + name;
    }
 
    @Override
    public void afterPropertiesSet() throws Exception {
        this.b = context.getBean(B.class);
    }
 
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.context = applicationContext;
    }
}
package com.example.tmp;
 
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
 
@Component
public class B {
    @Autowired
    private A a;
 
    private Integer age = 20;
 
    public Integer getAge() {
        return age;
    }
 
    public void setAge(Integer age) {
        this.age = age;
    }
}

測試 

啟動不報錯。

postman存取:http://localhost:8080/test1

後端結果:不報錯

postman結果: 20Tony

以上就是Spring迴圈依賴的解決方案詳解的詳細內容,更多關於Spring迴圈依賴的資料請關注it145.com其它相關文章!


IT145.com E-mail:sddin#qq.com