Spring框架自己具備多種執行依賴項注入的方式。 選項的靈活性是Spring框架的優點。 可是,並不是全部的依賴項注入選項都被視爲最佳實踐。 有些實際上很是貧窮。java
我爲咱們提供了一些示例,以審查必須使用的各類依賴項注入選項。編程
讓咱們以Spring Service爲例。 就咱們的目的而言,該服務具備一個返回字符串的方法。 咱們將使用「服務」,並使用Spring將其注入某些人造控制器中。 請記住,咱們只是在探索如何使用Spring Framework進行依賴項注入架構
Java框架
1 @Service 2 3 public class MyService { 4 5 public String getHello(){ 6 7 return "Hello"; 8 9 } 10 11 }
咱們的現場控制員擁有一項服務的公共財產。 咱們能夠註釋該字段,Spring將注入該服務的實例。ide
Java函數
1 @Controller 2 3 public class FieldController { 4 5 @Autowired 6 7 MyService myService; 8 9 public String saySomething(){ 10 11 return myService.getHello(); 12 13 } 14 15 }
這只是一個公共財產,沒有二傳手。 顯然,這不是一個好習慣。 也不推薦。學習
咱們能夠對此進行一些改進,並將對該字段的訪問權限設爲私有。 Spring Framework確實容許你自動鏈接私有字段。 你確實看到有人這樣作。 Spring將執行一些反射魔術來執行依賴項注入。測試
Javaui
@Controller this
1 public class PrivateFieldController { 2 3 @Autowired 4 5 private MyService myService; 6 7 public String saySomething(){ 8 9 return myService.getHello(); 10 11 } 12 13 } 14 15
儘管比僅使用私有字段更好,可是測試變得頭疼。 你要麼須要啓動Spring Context,要麼使用一些Spring實用程序來執行依賴注入以進行測試。 不是世界末日,而是使人討厭的。
咱們能夠經過爲私有財產提供二傳手來改善這一點。 Getter和Setter一般被認爲是面向對象編程中的最佳實踐。 經過註釋setter方法來指示Spring使用setter進行依賴項注入很簡單。
Java
1 @Controller 2 3 public class SetterController { 4 5 private MyService myService; 6 7 @Autowired 8 9 public void setMyService(MyService myService) { 10 11 this.myService = myService; 12 13 } 14 15 public String saySomething(){ 16 17 return myService.getHello(); 18 19 } 20 21 }
這是使用私有字段時的明顯改進。 有人會抱怨這太多代碼了。 但實際上,自South Park第一季以來,此類任務已在現代IDE中實現了自動化。
下一個選項是使用構造函數。 到目前爲止,這是咱們研究過的最佳方法。 使用構造函數設置注入的屬性時,沒必要提供自動裝配註釋。 這是一個很好的功能,能夠節省一些鍵入時間。 從Spring Framework版本4.2開始,用於依賴項注入的構造函數的註釋是可選的。
Java
1 @Controller 2 3 public class ConstructorController { 4 5 private MyService myService; 6 7 public ConstructorController(MyService myService) { 8 9 this.myService = myService; 10 11 } 12 13 public String saySomething(){ 14 15 return myService.getHello(); 16 17 } 18 19 }
基於構造函數的依賴注入無疑被認爲是最佳實踐。 曾經有一段時間我我的偏心基於setter的注入,可是後來我轉向了基於構造函數的注入。
咱們仍然能夠改善咱們的榜樣。 如今有兩個主要問題。 第一,咱們的服務類型是具體類型。 硬類型的依賴注入不是最佳實踐。
第二個問題是咱們注入的屬性未聲明爲final。 所以,從理論上講,該類能夠在實例化注入的屬性後對其進行修改。
依賴項注入的最佳實踐是利用接口,構造函數和最終屬性。
我已經創建了一個「最佳實踐」服務界面,並提供了一個服務實現,該服務實現帶有Spring Service註釋。
Java
1 public interface BpService { 2 3 String getHello(); 4 5 }
Java
1 @Service 2 3 public class BpServiceImpl implements BpService { 4 5 @Override 6 7 public String getHello() { 8 9 return "The Best Hello!"; 10 11 } 12 13 }
如今,使用Project Lombok進行依賴注入最佳實踐的祕訣在於:
如今,Project Lombok將爲聲明爲final的全部屬性生成一個構造函數。 Spring會自動使用Lombok提供的構造函數來自動裝配該類。
Java
1 @RequiredArgsConstructor 2 3 @Controller 4 5 public class BpFinalConstructorController { 6 7 private final BpService bpService; 8 9 public String saySomething(){ 10 11 return bpService.getHello(); 12 13 } 14 15 }
這是執行此操做的真正好方法。 你的代碼保持很是乾淨。 使用Spring時,一般須要多個自動裝配屬性。
當你須要添加另外一個bean時,只需聲明一個final屬性。
若是你重構而且再也不須要Spring託管的依賴項,則只需刪除final屬性。
你再也不須要維護設置器或構造函數代碼。 龍目島計劃減輕了你的負擔。
我如今在平常編碼中一直使用這種技術。 絕對是節省時間。 並致使更乾淨的代碼。 未使用的屬性和未使用的構造函數參數已一去不復返了。 如今,重構的痛苦就減輕了一點!