關于spring依賴注入的方式以及優(yōu)缺點
一.依賴注入的三種方式
1.通過構造器注入。(spring4.3之后,推薦使用)
2.通過setter注入。(spring4.3之前,推薦使用)
3通過filed注入。
二.三種方式的代碼示例:
Constructor注入
private AlarmContactService alarmContactService; private final AlarmService alarmService; private final SysUserService sysUserService; @Autowired public AlarmContactController(AlarmContactService alarmContactService, AlarmService alarmService, SysUserService sysUserService) { this.alarmContactService = alarmContactService; this.alarmService = alarmService; this.sysUserService = sysUserService; }
Setter注入
private AlarmContactService alarmContactService; private AlarmService alarmService; private SysUserService sysUserService; @Autowired public void setAlarmContactService(AlarmContactService alarmContactService) { this.alarmContactService = alarmContactService; } @Autowired public void setAlarmService(AlarmService alarmService) { this.alarmService = alarmService; } @Autowired public void setSysUserService(SysUserService sysUserService) { this.sysUserService = sysUserService; }
Field注入
@Autowired private AlarmContactService alarmContactService; @Autowired private AlarmService alarmService; @Autowired private SysUserService sysUserService;
三.3種方式的各優(yōu)點和缺點
三種方式的優(yōu)點分析
1.基于構造器注入,會固定依賴注入的順序,不允許我們創(chuàng)建的bean對象之間存在循環(huán)依賴關系,這樣Spring能解決循環(huán)依賴的問題。
2.基于setter注入,只有對象是需要被注入的時候,才會注入依賴,而不是在初始化的時候就注入。
3.在成員變量上寫上注解來注入,這種方式,精短,可讀性高,不需要多余的代碼,也方便維護。
三種方式的缺點分析
1.使用構造器注入的缺點是,當我們構造器需要注入的對象比較多時,會顯得我們的構造器,冗余,不美觀,可讀性差,也不易維護。
2.當我們選擇setter方法來注入的時候,我們不能將對象設為final的;
3.當我們在field變量上來實現注入的時候
a.這樣不符合JavaBean的規(guī)范,而且很有可能引起空指針;
b.同時也不能將對象標為final的;
c.類與DI容器高度耦合,我們不能在外部使用它;
d.類不通過反射不能被實例化(例如單元測試中),你需要用DI容器去實例化它,這更像集成測試;
來自Spring官方文檔的建議
在Spring 3.x 中,Spring團隊建議我們使用setter來注入:
而在Spring 4.x 中,Spring團隊不再建議我們使用setter來注入,改為了constructor:
Spring團隊通常建議使用構造器來注入,因為它允許一個應用程序組件實現為不可變對象,并確保所需的依賴項不是空。此外構造器注入組件總是返回一個完全初始化狀態(tài)的client客戶端(調用)。附注,大量的構造函數參數是一個糟糕的代碼習慣,看起來也很壞,這意味著類可能有太多的責任,應該被重構,以更好地解決適當的關注點分離。
三.解釋下什么是循環(huán)依賴
1. 循環(huán)依賴是什么?
Bean A 依賴 B,Bean B 依賴 A這種情況下出現循環(huán)依賴。
Bean A → Bean B → Bean A 或者 Bean A → Bean B → BeanC → Bean A
2. 循環(huán)依賴會產生什么結果?
當Spring正在加載所有Bean時,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中)。
假如,有如下循環(huán)依賴:
Bean A → Bean B → Bean C → BeanD → Bean A
但當存在循環(huán)依賴時,Spring將無法決定先創(chuàng)建哪個bean。這種情況下,Spring將產生異常BeanCurrentlyInCreationException。
Spring 4.3 的新特征:
在Spring 4.3 以后,如果我們的類中只有單個構造函數,那么Spring就會實現一個隱式的自動注入:
就是我去掉了構造器上的@Autowired注解,經測試后發(fā)現,程序能正常運行。alarmContactService,alarmService,sysUserService的依賴也被成功注入了。
private AlarmContactService alarmContactService; private final AlarmService alarmService; private final SysUserService sysUserService; public AlarmContactController(AlarmContactService alarmContactService, AlarmService alarmService, SysUserService sysUserService) { this.alarmContactService = alarmContactService; this.alarmService = alarmService; this.sysUserService = sysUserService; }
使用構造注入允許加入final,這也表示以后不能再被更改了。
到此這篇關于關于spring依賴注入的方式以及優(yōu)缺點的文章就介紹到這了,更多相關spring依賴注入內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
java Swing組件setBounds()簡單用法實例分析
這篇文章主要介紹了java Swing組件setBounds()簡單用法,結合實例形式分析了Swing組件setBounds()方法的功能與簡單使用方法,需要的朋友可以參考下2017-11-11MySQL中關鍵字UNION和UNION ALL的區(qū)別
本文主要介紹了MySQL中關鍵字UNION和UNION ALL的區(qū)別,深入探討UNION和UNION ALL的定義、用法、主要區(qū)別,具有一定的參考價值,感興趣的可以了解一下2024-06-06spring boot實戰(zhàn)之本地jar包引用示例
本篇文章主要介紹了spring boot實戰(zhàn)之本地jar包引用示例,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-10-10