Spring循環依賴的解決方案詳解
簡介
說明
本文用實例介紹如何解決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循環依賴的資料請關註WalkonNet其它相關文章!
推薦閱讀:
- 一文搞懂Spring循環依賴的原理
- Spring框架學習之Spring @Autowired實現自動裝配的代碼
- spring中向一個單例bean中註入非單例bean的方法詳解
- 淺談@Value和@Bean的執行順序問題
- Spring使用IOC與DI實現完全註解開發