Springboot中依賴注入的三種方式詳解
Springboot依賴注入Bean的方式
一、Field 注入/屬性注入
@Autowired注解的一大使用場(chǎng)景就是Field Injection。
@Controller public class UserController { @Autowired private UserService userService; }
通過(guò)Java的反射機(jī)制實(shí)現(xiàn),所以private的成員也可以被注入具體的對(duì)象
優(yōu)點(diǎn)
- 代碼少,簡(jiǎn)潔明了。
- 新增依賴十分方便,不需要修改原有代碼
缺點(diǎn)
- 容易出現(xiàn)空指針異常。Field 注入允許構(gòu)建對(duì)象實(shí)例時(shí)依賴的對(duì)象為空,導(dǎo)致空指針異常不能在啟動(dòng)時(shí)就爆出來(lái),只能在用到它時(shí)才發(fā)現(xiàn)。
空指針異常不是必現(xiàn)的,與bean的實(shí)例化順序有關(guān)。有時(shí),把依賴的bean改個(gè)名字就會(huì)報(bào)空指針異常。 - 會(huì)出現(xiàn)循環(huán)依賴的隱患。
二、set注入
Setter Injection需要依賴@Autowired注解,使用方式與Field Injection有所不同,F(xiàn)ield Injection時(shí)@Autowired是用在成員變量上,而Setter Injection的時(shí)候,@Autowired是用在成員變量的Setter函數(shù)上。
@Controller public class UserController { private UserService userService; @Autowired public void setUserService(UserService userService){ this.userService = userService; } }
通過(guò)調(diào)用成員變量的set方法來(lái)注入想要使用的依賴對(duì)象。
優(yōu)點(diǎn)
- 注入?yún)?shù)多的時(shí)候比較方便。構(gòu)造器注入?yún)?shù)太多了,顯得很笨重
- 能讓類在之后重新配置或者重新注入。
缺點(diǎn)
- 有一定風(fēng)險(xiǎn)。set注入是后初始化其依賴對(duì)象,如果一個(gè)對(duì)象在沒(méi)有完全初始化就被外界使用是不安全的(尤其是在多線程場(chǎng)景下更加突出)。
三、構(gòu)造器注入
Constructor Injection是構(gòu)造器注入,是Springboot最為推薦的一種使用方式。
@Controller public class UserController { private final UserService userService; public UserController(UserService userService){ this.userService = userService; } }
注意:
- 不能提供無(wú)參構(gòu)造方法,否則Springboot默認(rèn)會(huì)加載無(wú)參的構(gòu)造方法,Bean實(shí)例對(duì)象會(huì)為null
- Springboot官方建議使用final來(lái)修飾成員變量,然后通過(guò)構(gòu)造方法來(lái)進(jìn)行注入。原因:final修飾的成員變量是不能夠被修改的;不加final雖然也能注入Bean,但是若被其他人修改為null,可能會(huì)導(dǎo)致不必要的問(wèn)題,所以最好是加final。
通過(guò)對(duì)象構(gòu)建的時(shí)候建立關(guān)系,這種方式對(duì)對(duì)象創(chuàng)建的順序會(huì)有要求,當(dāng)然Spring會(huì)為你搞定這樣的先后順序,除非你出現(xiàn)循環(huán)依賴,然后就會(huì)拋出異常。
Spring 4.x 的時(shí)候,Spring 官方在對(duì)比構(gòu)造器注入和 Setter 注入時(shí),推薦使用構(gòu)造器注入方式:
優(yōu)點(diǎn)
- 保證注入的組件不可變
- 確保需要的依賴不為空
- 解決循環(huán)依賴的問(wèn)題(若有循環(huán)依賴會(huì)在項(xiàng)目啟動(dòng)時(shí)拋錯(cuò))
能夠保證注入的組件不可變,并且確保需要的依賴不為空。此外,構(gòu)造器注入的依賴總是能夠在返回客戶端(組件)代碼的時(shí)候保證完全初始化的狀態(tài)。
若手工寫(xiě)構(gòu)造方法覺(jué)得麻煩,也可以使用lombok中的@RequiredArgsConstructor
@RequiredArgsConstructor public class VerifyController { private final UserService userService; private final StudentService studentService; }
@RequiredArgsConstructor
@RequiredArgsConstructor 注解是針對(duì)標(biāo)有 @NonNull 注解的變量和 final 變量進(jìn)行參數(shù)的構(gòu)造方法。
到此這篇關(guān)于Springboot中依賴注入的三種方式詳解的文章就介紹到這了,更多相關(guān)Springboot依賴注入內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java中==與equals()及hashcode()三者之間的關(guān)系詳解
最近也是在讀Hollis的《深入理解Java核心技術(shù)》里面一節(jié)講到了equals()和hashcode()的關(guān)系,對(duì)于這個(gè)高頻面試點(diǎn),咱們需要認(rèn)真理清一下幾者之間的關(guān)系2022-10-10全面解析Spring Security 過(guò)濾器鏈的機(jī)制和特性
這篇文章主要介紹了Spring Security 過(guò)濾器鏈的機(jī)制和特性,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07詳解使用Java原生代理實(shí)現(xiàn)AOP實(shí)例
本篇文章主要介紹了詳解使用Java原生代理實(shí)現(xiàn)AOP實(shí)例,具有一定的參考價(jià)值,有興趣的可以了解一下。2017-01-01解決fcitx輸入法在IDEA中輸入法候選框無(wú)法跟隨光標(biāo)移動(dòng)的問(wèn)題
這篇文章主要介紹了解決fcitx輸入法在Intellij IDEA開(kāi)發(fā)工具中輸入法候選框無(wú)法跟隨光標(biāo)移動(dòng)的問(wèn)題,代碼簡(jiǎn)單易懂對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10Spring?Boot整合?NoSQL?數(shù)據(jù)庫(kù)?Redis詳解
這篇文章主要為大家介紹了Spring?Boot整合?NoSQL?數(shù)據(jù)庫(kù)?Redis詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09Java中雙冒號(hào)(::)運(yùn)算操作符用法詳解
這篇文章主要給大家介紹了關(guān)于Java中雙冒號(hào)(::)運(yùn)算操作符用法的相關(guān)資料,雙冒號(hào)運(yùn)算操作符是類方法的句柄,lambda表達(dá)式的一種簡(jiǎn)寫(xiě),這種簡(jiǎn)寫(xiě)的學(xué)名叫eta-conversion或者叫η-conversion,需要的朋友可以參考下2023-11-11