【Spring】Spring DI(依賴注入)詳解——自動裝配——手動裝配與自動裝配的區別

在spring開發中,依賴注入(Dependency Injection,DI)是實現松耦合和高內聚設計的重要模式。它使得對象的創建和管理與其依賴關系分離,從而提高了代碼的可維護性、可測試性和靈活性。Spring框架通過IoC(控制反轉)容器來實現DI,提供了多種方式來管理對象的依賴關系。

在實際開發中,我們經常需要在不同的類之間進行依賴注入,這就引出了手動裝配和自動裝配的概念。手動裝配需要開發者顯式地配置每個依賴,而自動裝配則讓Spring容器根據一定的規則自動注入依賴。 比如,你在一個餐廳點餐。手動裝配就像是你親自選擇每一道菜,告訴服務員你想要的具體菜品;而自動裝配則像是服務員根據你的口味和偏好,自動為你推薦并準備好一整套套餐。手動裝配雖然靈活,但需要更多的時間和精力,而自動裝配則簡化了流程,提高了效率。

一、手動裝配與自動裝配的區別
1. 手動裝配

手動裝配是指開發者需要在配置文件或代碼中明確指定每個依賴的創建和注入。開發者需要清楚每個Bean的依賴關系,并手動進行配置。

優點

  • 完全控制依賴的創建過程。

  • 適合復雜的依賴關系或需要特定配置的場景。

缺點

  • 配置繁瑣,增加了維護成本。

  • 難以應對依賴關系的變化。

2. 自動裝配

自動裝配是指Spring容器根據一定的規則自動注入依賴。Spring提供了多種自動裝配的方式,其中最常用的是byName和byType。

  • byName:根據Bean的名稱進行匹配。

  • byType:根據Bean的類型進行匹配。

優點

  • 減少了配置的復雜性。

  • 更加靈活,適應性強。

缺點

  • 可能會引入不必要的依賴,增加調試難度。

  • 對于多個同類型的Bean,可能導致沖突。

二、自動裝配的實現方式

下面我們通過具體示例來演示自動裝配的實現,分別介紹byName和byType的方式。

1. 創建服務和依賴類

首先,我們定義兩個服務類UserServiceOrderService,其中OrderService依賴于UserService

//?UserService.java
public?class?UserService?{public?void?registerUser()?{System.out.println("User?registered?successfully.");}
}//?OrderService.java
public?class?OrderService?{private?UserService?userService;//?通過Setter方法注入UserServicepublic?void?setUserService(UserService?userService)?{this.userService?=?userService;}public?void?placeOrder()?{System.out.println("Order?placed.");userService.registerUser();?//?調用UserService的方法}
}

解釋

  • UserService類負責用戶注冊邏輯。

  • OrderService類依賴于UserService,通過Setter方法進行注入。

2. 手動裝配的實現

我們首先實現手動裝配的方式,通過Spring的Java配置來創建這些Bean。

import?org.springframework.context.ApplicationContext;
import?org.springframework.context.annotation.Bean;
import?org.springframework.context.annotation.Configuration;
import?org.springframework.context.annotation.AnnotationConfigApplicationContext;@Configuration
public?class?ManualConfig?{@Beanpublic?UserService?userService()?{return?new?UserService();?//?創建UserService實例}@Beanpublic?OrderService?orderService()?{OrderService?orderService?=?new?OrderService();orderService.setUserService(userService());?//?手動注入UserServicereturn?orderService;}
}

解釋

  • ManualConfig類是手動裝配的配置類,使用@Bean注解定義Bean。

  • orderService()方法中顯式調用setUserService()進行依賴注入。

3. 自動裝配的實現

接下來,我們使用自動裝配的方式來實現同樣的功能。

import?org.springframework.context.ApplicationContext;
import?org.springframework.context.annotation.Bean;
import?org.springframework.context.annotation.Configuration;
import?org.springframework.context.annotation.AnnotationConfigApplicationContext;
import?org.springframework.context.annotation.ComponentScan;
import?org.springframework.stereotype.Component;@Configuration
@ComponentScan(basePackages?=?"com.example")?//?自動掃描指定包中的組件
public?class?AutoConfig?{@Beanpublic?UserService?userService()?{return?new?UserService();?//?創建UserService實例}
}//?使用@Component注解標記OrderService為Spring管理的組件
@Component
public?class?OrderService?{private?UserService?userService;//?自動裝配UserService(byType)public?OrderService(UserService?userService)?{this.userService?=?userService;}public?void?placeOrder()?{System.out.println("Order?placed.");userService.registerUser();?//?調用UserService的方法}
}

解釋

  • @ComponentScan注解用于自動掃描指定包中的組件。

  • OrderService類使用構造器注入的方式自動裝配UserService,Spring會根據類型自動匹配。

4. 啟動應用

最后,我們創建一個主類來啟動Spring應用并獲取OrderService Bean。

public?class?Main?{public?static?void?main(String[]?args)?{//?創建Spring容器ApplicationContext?context?=?new?AnnotationConfigApplicationContext(AutoConfig.class);//?獲取OrderService?BeanOrderService?orderService?=?context.getBean(OrderService.class);orderService.placeOrder();?//?調用下訂單的方法}
}

解釋

  • AnnotationConfigApplicationContext用于創建基于Java配置的Spring容器。

  • 通過context.getBean(OrderService.class)獲取OrderService的實例,并調用其placeOrder()方法。

三、總結

手動裝配和自動裝配是Spring中依賴注入的兩種重要方式。手動裝配提供了對依賴關系的完全控制,但配置繁瑣;而自動裝配則簡化了配置過程,提高了開發效率,但可能引入不必要的復雜性。

通過本次講解,我們深入理解了自動裝配的byName和byType方式,以及手動裝配的實現。掌握這些知識將幫助我們在實際項目中更靈活地管理對象之間的依賴關系,提升代碼的可維護性和可測試性。

希望通過這次的學習,能夠幫助你在Java開發中更好地應用Spring框架的依賴注入特性。在實際開發中,可以根據具體的需求和場景選擇合適的裝配方式。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/64649.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/64649.shtml
英文地址,請注明出處:http://en.pswp.cn/web/64649.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

EZ-USB? FX3 USB 5 Gbps 外設控制器

EZ-USB? FX3 USB 5 Gbps 外設控制器 EZ-USB? FX3 提供 USB 5Gbps 至 32 位數據總線,并配備 ARM9,可為任何系統添加 USB 3.0 連接 英飛凌的 EZ-USB? FX3 是業界用途最廣泛的 USB 外圍設備控制器,可以為幾乎任何系統添加 USB 5Gbps 連接。 …

【數據倉庫】spark大數據處理框架

文章目錄 概述架構spark 架構角色下載安裝啟動pyspark啟動spark-sehll啟動spark-sqlspark-submit經驗 概述 Spark是一個性能優異的集群計算框架,廣泛應用于大數據領域。類似Hadoop,但對Hadoop做了優化,計算任務的中間結果可以存儲在內存中&a…

數據庫容災備份的意義+分類+執行工具!

數據庫容災解決方案的背景 數據庫容災(Disaster Recovery,DR)解決方案的背景主要源于企業對數據安全性、業務連續性和系統高可用性的需求。隨著數字化轉型的加速,企業的數據量迅猛增長,數據庫已成為支撐核心業務的關鍵…

PDF怎么壓縮得又小又清晰?5種PDF壓縮方法

PDF 文件在日常辦公與學習中使用極為頻繁,可想要把它壓縮得又小又清晰卻困難重重。一方面,PDF 格式本身具有高度兼容性,集成了文字、圖像、矢量圖等多樣元素,壓縮時難以兼顧不同元素特性,稍不注意,文字就會…

SpringBoot數據字典字段自動生成對應code和desc

效果:接口會返回orderType,但是這個orderType是枚舉的類型(1,2,3,4),我想多返回一個orderTypeDesc給前端展示,這樣前端就可以直接拿orderTypeDesc使用了。 1. 定義注解 …

【YashanDB知識庫】imp導入數據庫時,報錯YAS-08023

本文內容來自YashanDB官網,原文內容請見 https://www.yashandb.com/newsinfo/7849010.html?templateId1718516 **【問題分類】**數據導入導出 **【關鍵字】**imp、YAS-08023 【問題描述】 導出數據庫時,使用以下命令,導出正常&#xff1…

又一年。。。。。。

2024,渾渾噩噩的一年。 除了100以內的加減法(數據,數據,還是數據。。。。。。),似乎沒做些什么。 臉盲癥越來越重的,怕是哪天連自己都不認得自己的了。 看到什么,聽到什…

FreeRTOS: ISR(中斷服務例程)和 TCB(任務控制塊)

在討論 ISR(中斷服務例程)和 TCB(任務控制塊,Task Control Block)時,我們實際上是在探討 FreeRTOS 中兩個不同但又相互關聯的概念:一個是用于處理硬件或軟件觸發的中斷事件,另一個是…

GoldenDB組件及對應的用戶和進程

1. GoldenDB組件及對應的用戶和進程 GoldenDB數據庫由管理節點、全局事務節點GTM、計算節點CN、數據節點DN等組成。 1.1. 管理節點 管理節點分為集群管理、Insight運維管理平臺(InsightServer、RDB、ZK)。 1.1.1. 集群管理 1. 集群管理包括Metadatas…

OpenStack系列第四篇:云平臺基礎功能與操作(Dashboard)

文章目錄 1. 鏡像(Image)添加鏡像查看鏡像刪除鏡像 2. 卷(Volume)創建卷查看卷刪除卷 3. 網絡(虛擬網絡)創建網絡查看網絡刪除網絡 4. 實例類型創建實例類型查看實例類型刪除實例類型 4. 密鑰對&#xff08…

CSDN編輯器

這里寫自定義目錄標題 歡迎使用Markdown編輯器新的改變功能快捷鍵合理的創建標題,有助于目錄的生成如何改變文本的樣式插入鏈接與圖片如何插入一段漂亮的代碼片生成一個適合你的列表創建一個表格設定內容居中、居左、居右SmartyPants 創建一個自定義列表如何創建一個…

MTK 平臺關于WIFI 6E P2P的解說

一 前言 官方 P2P 6E 設計原理,請查看這個網站 hostap - hostapd/wpa_supplicant 配置:p2p_6ghz_disable 允許上層指定是否允許6G連接 僅允許6G用于WFD –不允許6G用于純P2P 缺點:存在很多 IOT issues 如:一些物聯網設備無法識別6G類/信道,可能存在物聯網問…

四大自平衡樹對比:AVL樹、紅黑樹、B樹與B+樹

AVL樹、紅黑樹、B樹和B樹的對比與應用場景 樹系列相關文章(置頂) 1、從鏈表到平衡樹:二叉查找樹的退化與優化 2、自平衡二叉查找樹:如何讓二叉查找樹始終保持高效 3、AVL樹入門:理解自平衡二叉查找樹的基礎 4、紅黑樹全…

Linux下讀取Windows下保存的文件,報錯信息中出現“^M“時如何解決?【由于Windows和Linux的換行方式不同造成的-提供兩種轉換方式】

Windows 和 Linux 的文本文件使用的換行符不同: Windows 使用 \r\n (回車 換行)。Linux 使用 \n (換行)。 因此,當在 Linux 系統上運行帶有 Windows 換行符的腳本或讀取相關文件時,可能會出現…

簡易內存池(下)

提示&#xff1a;文章 文章目錄 前言一、背景二、2.1Ace代碼 三、3.1 總結 前言 前期疑問&#xff1a; 本文目標&#xff1a; 一、背景 最近 二、 2.1 Ace代碼 Aced代碼形式如下 #include <stdbool.h> #include <stdio.h> #include <malloc.h> #inclu…

npm ERR! ECONNRESET 解決方法

問題&#xff1a;npm 命令遇到的錯誤是 ECONNRESET&#xff0c;這通常與網絡連接問題相關。設置代理解決問題。 一、查看當前代理設置 npm config get proxy npm config get https-proxy二、設置代理 npm config set proxy http://your-proxy-address:port npm config set h…

【UE5】UnrealEngine源碼構建2:windows構建unreal engine 5.3.2

參考大神知乎的文章:UE5 小白也能看懂的源碼編譯指南 據說會耗費400G的空間。 代碼本身并不大,可能是依賴特別多,畢竟看起來UE啥都能干,核心還是c++的, 【UE5】UnrealEngine源碼構建1:tag為5.3.2源碼clone 本著好奇+ 學習的態度,想著也許有機會能更為深入的熟悉UE的機制…

Day60 圖論part10

今天大家會感受到 Bellman_ford 算法系列在不同場景下的應用。 建議依然是:一刷的時候,能理解 原理,知道Bellman_ford 解決不同場景的問題 ,照著代碼隨想錄能抄下來代碼就好,就算達標。 二刷的時候自己嘗試獨立去寫,三刷的時候 才能有一定深度理解各個最短路算法。 Bell…

在Linux上獲取MS(如Media Server)中的RTP流并錄制為雙軌PCM格式的WAV文件

在Linux上獲取MS(如Media Server)中的RTP流并錄制為雙軌PCM格式的WAV文件 一、RTP流與WAV文件格式二、實現步驟三、偽代碼示例四、C語言示例代碼五、關鍵點說明六、總結在Linux操作系統上,從媒體服務器(如Media Server,簡稱MS)獲取RTP(Real-time Transport Protocol)流…

Vue3 簡介

Vue3 簡介 最新版本&#xff1a; v3.5.13 1、性能提升 打包大小減少 41% - 初次渲染快 55%, 更新渲染快 133%內存減少 54% 2、源碼的升級 使用 Proxy 代替 defineProperty 實現響應式。重寫虛擬 DOM 的實現和 Tree-Shaking 3、擁抱TypeScript Vue3 可以更好的支持 TypeSc…