前言
以下內(nèi)容為本人學習Spring Boot的依賴注入和自動注入
與ChatGpt提問后對其回答進行部分修改
(有的錯誤實在是離譜 = =)、格式調(diào)整等操作后的答案,可能對于其中部分細節(jié)(是錯是對,能力有限有的看不出來 = =),并未做深入探究
,大家感興趣的話可以自行驗證。
詳細講講依賴注入
依賴注入
(Dependency Injection
,簡稱DI
)的概念最早由Martin Fowler
在2004
年提出。依賴注入是一種軟件設計模式
,旨在解耦和組織對象之間的依賴關(guān)系
,以提高代碼的可維護性和可測試性
。
在傳統(tǒng)的編程模式中,一個對象通常負責自己創(chuàng)建和管理所依賴的其他對象
。這種緊密耦合的設計模式會導致代碼的脆弱性
,因為對象需要直接知道它所依賴的對象的實現(xiàn)細節(jié)
,并且對于變化會很敏感
(使用過傳統(tǒng)編程模式的應該深有體會)。此外,這也會增加代碼的復雜性
,使得對象之間的關(guān)系變得難以理解和維護
。
依賴注入的目標是通過將依賴對象的創(chuàng)建和管理責任從對象本身轉(zhuǎn)移到外部容器中
,以實現(xiàn)松耦合和可維護性
。在依賴注入中,對象聲明它所需要的依賴關(guān)系
,而不需要關(guān)心如何創(chuàng)建或獲取
這些依賴對象。
依賴注入的核心思想是控制反轉(zhuǎn)
(Inversion of Control,簡稱IoC
)。在傳統(tǒng)的編程模式中,對象自己控制創(chuàng)建和管理
它所依賴的對象,而在依賴注入中,這種控制被反轉(zhuǎn)了。對象不再自己創(chuàng)建依賴對象
,而是通過外部容器(通常是一個IoC容器)來創(chuàng)建和注入依賴對象
。
依賴注入可以通過以下幾種方式實現(xiàn)
:
-
構(gòu)造函數(shù)注入(Constructor Injection)
:對象通過構(gòu)造函數(shù)
接收依賴對象作為參數(shù)
。在創(chuàng)建對象時,依賴對象會被傳遞給構(gòu)造函數(shù)
進行注入。這種方式通常提供了更好的不變性和一致性
。 -
Setter方法注入(Setter Injection)
:對象通過Setter方法設置依賴對象
。在對象創(chuàng)建后,通過調(diào)用相應的Setter方法來注入依賴對象
。這種方式可以提供更靈活的注入方式,允許依賴對象在對象創(chuàng)建后被替換
。 -
接口注入(Interface Injection)
:對象通過實現(xiàn)特定接口,從而暴露用于注入依賴對象的方法
。容器在創(chuàng)建對象后,會調(diào)用接口方法并注入依賴對象
。
依賴注入的優(yōu)點
包括:
-
松耦合
:依賴對象與被依賴對象之間的耦合度降低,對象的職責更加單一,易于理解和維護。 -
可測試性
:依賴注入使得測試變得更加容易??梢酝ㄟ^注入模擬對象(Mock Objects)來進行單元測試和模塊測試
。 -
可重用性
:通過依賴注入,依賴對象可以被多個對象共享和重用
,避免了重復創(chuàng)建和管理相同的依賴對象。 -
可擴展性
:依賴注入使得應用程序的組件之間的關(guān)系更加靈活
,可以輕松添加、替換和升級依賴對象
。
現(xiàn)代的開發(fā)框架和容器(如Spring
框架、Spring Boot
和Google Guice
)提供了依賴注入
的實現(xiàn)。它們通過注解、配置文件或其他方式
,實現(xiàn)了依賴注入的自動化和便利性,使得開發(fā)者可以專注于業(yè)務邏輯的實現(xiàn)而不必過多關(guān)注依賴對象的創(chuàng)建和管理。
給出依賴的三種注入的方式的示例
當談到依賴注入的三種主要方式時(構(gòu)造函數(shù)注入、Setter方法注入和接口注入
),我將為你提供每種方式的示例代碼。
-
構(gòu)造函數(shù)注入(Constructor Injection)
的示例:
public class UserService {
private UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
// ...
}
在上面的示例中,UserService
類通過構(gòu)造函數(shù)接收一個UserRepository
依賴對象,并將其賦值給成員變量userRepository
。這種方式可以在創(chuàng)建UserService
對象時,將UserRepository
的實例傳遞給構(gòu)造函數(shù)來進行注入。
-
Setter方法注入(Setter Injection)
的示例:
public class UserService {
private UserRepository userRepository;
public void setUserRepository(UserRepository userRepository) {
this.userRepository = userRepository;
}
// ...
}
在上述示例中,UserService
類通過Setter方法 setUserRepository()
接收一個UserRepository
依賴對象,并將其賦值給成員變量userRepository
。這樣,在創(chuàng)建UserService
對象后,可以調(diào)用setUserRepository()
方法來注入UserRepository
的實例。
-
接口注入(Interface Injection)
的示例:
public interface DiscountService {
void setDiscountProvider(DiscountProvider discountProvider);
}
public class DiscountServiceImpl implements DiscountService {
private DiscountProvider discountProvider;
@Override
public void setDiscountProvider(DiscountProvider discountProvider) {
this.discountProvider = discountProvider;
}
// ...
}
在上述示例中,DiscountService
是一個接口,定義了一個setDiscountProvider()
方法,用于接收DiscountProvider
依賴對象。DiscountServiceImpl
類實現(xiàn)了該接口,并通過實現(xiàn)方法setDiscountProvider()
來注入DiscountProvider
的實例。
這些示例展示了依賴注入的不同方式,通過構(gòu)造函數(shù)、Setter方法或接口方法來接收依賴對象,并將其賦值給類的成員變量或?qū)傩?。在實際應用中,通常會結(jié)合使用這些方式,根據(jù)具體的需求和場景選擇適合的注入方式。
從概念上講講自動注入
自動注入(Autowired)
是依賴注入(Dependency Injection,DI)
的一種實現(xiàn)
方式,最早由Spring框架
引入并提出。
在傳統(tǒng)的依賴注入方式
中,開發(fā)人員需要顯式地在代碼中聲明依賴關(guān)系并手動進行依賴對象的注入
。這種方式需要編寫大量的重復代碼,并且容易出錯。
為了簡化依賴注入的過程
,Spring框架引入了自動注入的概念
。自動注入允許開發(fā)人員使用特定的注解來標記依賴對象
,而無需顯式地進行依賴注入的代碼編寫
??蚣軙?code>自動查找和注入匹配的依賴對象,減少了手動注入的工作量,提高了開發(fā)效率。
自動注入的概念最早在Spring框架的早期版本
中被提出。通過在目標類的字段、構(gòu)造函數(shù)或Setter方法上添加@Autowired注解
,Spring容器會在創(chuàng)建對象
時自動查找匹配的依賴對象
,并將其注入
到相應的位置。自動注入是根據(jù)類型進行匹配的
,如果存在多個匹配的依賴對象
,可以使用@Qualifier注解或通過名稱
來指定具體的依賴對象。
自動注入帶來了以下好處:
-
簡化開發(fā)
:自動注入減少了手動注入的代碼量,使代碼更簡潔和易于維護。 -
減少配置
:開發(fā)人員無需手動配置每個依賴對象的注入,框架會自動完成依賴的查找和注入。 -
提高可測試性
:通過自動注入,可以更容易地進行單元測試,可以輕松地替換依賴對象進行測試。
Spring框架的自動注入成為了它的核心特性之一
,并且受到了廣泛的應用和認可
。后續(xù)的框架和技術(shù)也借鑒了Spring的自動注入概念,提供了類似的功能來簡化依賴注入的過程。
Spring Boot中注解@Autowired,自動注入注解默認使用哪種注入方式
@Autowired注解
可以使用以下幾種依賴注入的方式:
-
按照類型進行注入(byType)
:這是@Autowired注解的默認方式
,它會根據(jù)屬性的類型在容器中查找對應的Bean
,如果找到唯一的一個Bean
,則進行注入
。如果沒有找到或者找到多個
相同類型的Bean,則會拋出異常
。這種方式可以用在字段、構(gòu)造方法或者setter方法上。 -
按照名稱進行注入(byName)
:這種方式需要配合@Qualifier
注解來指定Bean的名稱
,它會根據(jù)屬性的名稱在容器中查找對應的Bean,如果找到則進行注入
。如果沒有找到,則會拋出異常。這種方式可以用在字段、構(gòu)造方法或者setter方法上。 -
按照構(gòu)造方法進行注入(constructor)
:這種方式是通過Bean對象的構(gòu)造方法參數(shù)類型和容器中的Bean類型進行匹配,如果找到唯一的一個相同類型的Bean,則通過構(gòu)造方法進行注入。如果沒有找到或者找到多個相同類型的Bean,則會拋出異常。這種方式只能用在構(gòu)造方法上
。
一般來說,按照類型進行注入
是最常用和方便
的方式,但是如果你需要更精確地
指定要注入的Bean,或者你想保證依賴對象不為空
,那么你可以使用按照名稱或者按照構(gòu)造方法進行注入
。
給我一些上面自動注入的簡單示例
好的,我將給你一些簡單的示例。
按照類型
進行注入的示例(大部分用的都是這種
):
@Component
public class FooService {
//在字段上使用@Autowired注解,按照類型進行注入
@Autowired
private FooFormatter fooFormatter;
}
@Component
public class FooFormatter {
public String format() {
return "foo";
}
}
按照名稱
進行注入的示例:
@Component
public class BarService {
//在字段上使用@Autowired和@Qualifier注解,按照名稱進行注入
@Autowired
@Qualifier("barFormatter")
private BarFormatter barFormatter;
}
@Component("barFormatter")
public class BarFormatter {
public String format() {
return "bar";
}
}
按照構(gòu)造方法
進行注入的示例:
@Component
public class BazService {
private BazFormatter bazFormatter;
//在構(gòu)造方法上使用@Autowired注解,按照類型進行注入
@Autowired
public BazService(BazFormatter bazFormatter) {
this.bazFormatter = bazFormatter;
}
}
@Component
public class BazFormatter {
public String format() {
return "baz";
}
}
依賴注入和自動注入的關(guān)聯(lián)以及不同點
依賴注入(Dependency Injection,簡稱DI)和自動注入(Autowired)
是相關(guān)但不完全相同
的概念。下面我將解釋它們之間的關(guān)聯(lián)和不同點:
關(guān)聯(lián)
:
-
自動注入是依賴注入的一種實現(xiàn)方式
。自動注入是指在容器啟動或?qū)ο髣?chuàng)建時,容器自動將所需的依賴對象注入到目標對象中,而無需手動顯式地進行依賴注入
。 -
在
Spring框架及其衍生的Spring Boot
中,使用@Autowired
注解實現(xiàn)自動注入
。通過在目標對象的字段、構(gòu)造函數(shù)或Setter方法上使用@Autowired注解
,Spring容器會根據(jù)類型或名稱自動查找并注入相應的依賴對象。
不同點:
-
控制權(quán)
:依賴注入
是一種設計模式
,強調(diào)將依賴對象的創(chuàng)建和管理責任轉(zhuǎn)移到外部容器
中。在依賴注入中,對象聲明自己需要的依賴,但并不負責創(chuàng)建或獲取依賴對象
。相反,自動注入
是依賴注入的一種具體實現(xiàn)方式
,它是由容器在對象創(chuàng)建時自動完成依賴對象
的注入。 -
顯式性
:依賴注入
通常需要在代碼中顯式地
聲明依賴關(guān)系,即通過構(gòu)造函數(shù)、Setter方法或接口方法
來接收依賴對象。這樣可以清晰地表達對象之間的依賴關(guān)系。而自動注入
則不需要顯式地聲明依賴關(guān)系
,容器會自動根據(jù)配置或默認規(guī)則完成注入
。 -
靈活性:依賴注入提供了
更大的靈活性
,允許對象在創(chuàng)建后替換依賴對象
,或者在不同的環(huán)境中使用不同的依賴對象。通過手動注入,可以更容易地進行單元測試和模塊替換。相比之下,自動注入的靈活性相對較低
,依賴對象的選擇通常由容器的配置或規(guī)則
確定。
總結(jié)來說,依賴注入是一種設計模式
,強調(diào)通過外部容器將依賴對象注入到目標對象
中,以提高代碼的可維護性和可測試性。
自動注入是依賴注入的一種具體實現(xiàn)方式
,它通過使用@Autowired注解
或其他類似的機制,在對象創(chuàng)建時自動完成依賴對象的注入
。自動注入減少了手動注入的代碼量,但相對來說可能犧牲了一些靈活性。文章來源:http://www.zghlxwxcb.cn/news/detail-459722.html
在Spring Boot
中,可以使用@Autowired注解
實現(xiàn)自動注入,從而簡化依賴注入的過程。文章來源地址http://www.zghlxwxcb.cn/news/detail-459722.html
到了這里,關(guān)于Spring Boot中的依賴注入和自動注入的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!