- Spring Boot進階:原理、實戰與面試題分析
- 鄭天民
- 789字
- 2022-07-05 09:41:41
2.1.1 字段注入
首先,我們來看字段注入。想要在一個類中通過字段的形式注入某個對象,就可以使用這個方式,示例代碼如代碼清單2-2所示。
代碼清單2-2 字段注入示例代碼
public class ClientService { @Autowired private HealthRecordService healthRecordService; public void recordUserHealthData() { healthRecordService.recordUserHealthData(); } }
可以看到,通過@Autowired注解,字段注入的實現方式非常簡單而直接,代碼的可讀性也很高。事實上,字段注入是三種注入方式中最常用,也是最容易使用的一種,但它也是三種注入方式中最應該避免使用的。如果你使用過IDEA,可能會遇到“Field injection is not recommended”這個提示,告訴你不建議使用字段注入。針對這一點,你可能會覺得很詫異。我們來分析一下原因。
1)字段注入的最大問題是對象的外部可見性。正如在前面的ClientService類中,我們通過定義一個私有變量healthRecordService來注入該接口的實例。顯然,這個實例只能在ClientService類中被訪問,脫離了容器環境就無法進行訪問,如代碼清單2-3所示。
代碼清單2-3 脫離容器使用ClientService示例代碼
ClientService clientService = new ClientService(); clientService.recordUserHealthData();
執行這段代碼的結果就是拋出一個NullPointerException空指針異常,原因是無法在ClientService的外部實例化HealthRecordService對象。采用字段注入,類與容器的耦合度過高,我們無法脫離容器來使用目標對象。如果我們編寫測試用例來驗證ClientService類的正確性,那么想要使用HealthRecordService對象,就只能通過反射的方式,這種做法實際上是不符合JavaBean開發規范的,而且可能導致一直無法發現空指針異常。
2)字段注入的第二個問題是可能導致潛在的循環依賴。所謂循環依賴,就是兩個類之間互相進行注入,示例代碼如代碼清單2-4所示。
代碼清單2-4 基于字段注入的循環依賴示例代碼
public class ClassA { @Autowired private ClassB classB; } public class ClassB { @Autowired private ClassA classA; }
顯然,這里的ClassA和ClassB發生了循環依賴。上述代碼在Spring中是合法的,容器啟動時并不會報任何錯誤,而只有在使用到具體某個ClassA或ClassB時才會報錯。
3)字段注入的第三個問題是我們無法設置需要注入的對象為final,也無法注入那些不可變對象,這是因為字段必須在類實例化時進行實例化。
基于以上三點,IDEA以及Spring官方都不推薦開發人員使用字段注入這種方式。那么,我們推薦的注入方式是哪種呢?答案是構造器注入。
- Oracle WebLogic Server 12c:First Look
- 在最好的年紀學Python:小學生趣味編程
- INSTANT OpenCV Starter
- Android項目開發入門教程
- JavaScript:Functional Programming for JavaScript Developers
- Python漫游數學王國:高等數學、線性代數、數理統計及運籌學
- Java SE實踐教程
- C#程序設計(項目教學版)
- Essential C++(中文版)
- Raspberry Pi Robotic Projects(Third Edition)
- 微信小程序開發實戰:設計·運營·變現(圖解案例版)
- C++程序設計教程
- JavaEE架構與程序設計
- Web前端測試與集成:Jasmine/Selenium/Protractor/Jenkins的最佳實踐
- Java EE輕量級解決方案:S2SH