Spring IOC基于XML和注解管理Bean

IoC 是 Inversion of Control 的簡寫,譯為“ 控制反轉 ”,它不是一門技術,而是一種設計思想,是一個重要的面向對象編程法則,能夠指導我們如何設計出 松耦合、更優良的程序。

Spring 通過 IoC 容器來管理所有 Java 對象的實例化和初始化,控制對象與對象之間的依賴關系。將由 IoC 容器管理的 Java 對象稱為 Spring Bean,它與使用關鍵字 new 創建的 Java 對象沒有任何區別。

IoC 容器是 Spring 框架中最重要的核心組件之一,它貫穿了 Spring 從誕生到成長的整個過程。

IOC容器

1.控制反轉,依賴注入

控制反轉(Inversion of Control,簡稱IoC)是一種軟件設計原則,它將傳統的程序控制流程反轉過來,即由被調用者控制調用者的執行過程。這樣做的好處在于降低了代碼之間的耦合性,使得代碼更加靈活、可維護和可擴展。

一個典型的控制反轉例子是使用依賴注入(Dependency Injection,簡稱DI)。依賴注入是控制反轉的一種實現方式,它通過將依賴關系從代碼內部移動到外部來實現解耦。

假設我們有一個簡單的應用程序,其中包含一個服務類 MessageService 負責發送消息,并且這個服務類依賴于一個用于實際發送消息的 MessageSender 接口。在傳統的實現中,MessageService 通常會直接創建一個特定的 MessageSender 實例,但在使用控制反轉的思想下,我們會將 MessageSender 的創建和注入從 MessageService 中分離出來。

傳統實現(無控制反轉):

public class MessageService {private MessageSender messageSender;public MessageService() {// 在構造函數中直接實例化特定的 MessageSender 實例this.messageSender = new EmailMessageSender(); // 假設使用 EmailMessageSender 發送消息}public void sendMessage(String message) {messageSender.send(message);}
}

使用控制反轉(依賴注入):

public class MessageService {private MessageSender messageSender;public MessageService(MessageSender messageSender) {// 通過構造函數接收一個 MessageSender 實例,由外部注入this.messageSender = messageSender;}public void sendMessage(String message) {messageSender.send(message);}
}

現在,使用控制反轉,我們將 MessageSender 的實例化過程交由調用者來完成。這樣做的好處是,在應用程序的其他地方,我們可以根據需要輕松地更換不同的 MessageSender 實現(例如,使用短信發送消息而不是電子郵件),而無需修改 MessageService 的代碼。同時,這也使得單元測試變得更容易,因為我們可以輕松地注入一個模擬的 MessageSender 實例來進行測試。

舉例:
如果你希望在使用短信發送消息而不是電子郵件時進行更改,只需更改 MessageService 類的構造函數中注入的 MessageSender 實例即可。這就是控制反轉的好處,它使得我們可以在應用程序的其他地方配置不同的實現,并且只需更改依賴注入的部分,而不需要修改 MessageService 的實現代碼。

讓我們看一下如何在 MessageService 中使用短信發送消息的例子:

  • 創建一個用于發送短信的實現類 SmsMessageSender:
public class SmsMessageSender implements MessageSender {public void send(String message) {// 實現發送短信的邏輯System.out.println("Sending SMS: " + message);}
}
  • 現在,在使用 MessageService 的地方,通過構造函數將 SmsMessageSender 注入:
public class MyApp {public static void main(String[] args) {// 使用短信發送消息MessageSender smsSender = new SmsMessageSender();MessageService messageService = new MessageService(smsSender);// 發送消息messageService.sendMessage("Hello, this is a text message!");}
}

通過這樣的更改,MessageService 現在使用 SmsMessageSender 來發送消息而不是之前的 EmailMessageSender,而且這個更改只發生在應用程序的一個地方,使得代碼更易于維護和擴展。同時,你可以根據需要在其他地方繼續使用 EmailMessageSender,并且無需對 MessageService 的實現進行任何修改。

set注入和依賴注入

在依賴注入(Dependency Injection,DI)的實踐中,有兩種常見的注入方式:構造函數注入(Constructor Injection)和屬性/方法注入(Setter Injection)。

構造函數注入(Constructor Injection):
構造函數注入是將依賴通過類的構造函數傳遞進來的方式。在這種注入方式中,類的依賴關系在創建對象時就被明確地傳遞給對象,保證了對象在被實例化后就具備了所需的依賴。這種注入方式通常被認為是推薦的注入方式,因為它在對象創建過程中就明確了依賴關系,使得對象在創建后處于一種可用的狀態。
示例:構造函數注入的Java代碼

public class MessageService {private MessageSender messageSender;public MessageService(MessageSender messageSender) {this.messageSender = messageSender;}// 業務邏輯方法使用依賴發送消息public void sendMessage(String message) {messageSender.send(message);}
}

屬性/方法注入(Setter Injection):
屬性/方法注入是通過setter方法或者普通方法將依賴傳遞給對象的方式。在這種注入方式中,對象首先由默認構造函數創建,然后通過setter方法或者普通方法設置其依賴。由于依賴在創建對象后才被注入,因此在對象實例化時,它可能處于不完整或不可用的狀態,這是它與構造函數注入的主要區別。
示例:屬性/方法注入的Java代碼

public class MessageService {private MessageSender messageSender;// 通過setter方法注入依賴public void setMessageSender(MessageSender messageSender) {this.messageSender = messageSender;}// 業務邏輯方法使用依賴發送消息public void sendMessage(String message) {messageSender.send(message);}
}

需要注意的是,屬性/方法注入可能導致對象處于不完整或不可用的狀態,因此需要在使用對象之前確保其依賴已經被正確注入。另一方面,構造函數注入在對象創建時就明確了依賴關系,因此更容易維護和確保對象的完整性。

通常情況下,如果可能,推薦使用構造函數注入,因為它更符合依賴注入的原則,能夠在對象創建時就將依賴傳遞進來,減少了對象的不穩定性。而屬性/方法注入則適用于一些特殊情況,例如使用框架進行依賴注入時可能更為便利,或者在某些場景下靈活性要求較高時使用。

2.IoC容器在Spring的實現

Spring 的 IoC 容器就是 IoC思想的一個落地的產品實現。IoC容器中管理的組件也叫做 bean。在創建 bean 之前,首先需要創建IoC 容器。Spring 提供了IoC 容器的兩種實現方式:

①BeanFactory

這是 IoC 容器的基本實現,是 Spring 內部使用的接口。面向 Spring 本身,不提供給開發人員使用。

②ApplicationContext

BeanFactory 的子接口,提供了更多高級特性。面向 Spring 的使用者,幾乎所有場合都使用 ApplicationContext 而不是底層的 BeanFactory。

③ApplicationContext的主要實現類
在這里插入圖片描述

類型名簡介
ClassPathXmlApplicationContext通過讀取類路徑下的 XML 格式的配置文件創建 IOC 容器對象
FileSystemXmlApplicationContext通過文件系統路徑讀取 XML 格式的配置文件創建 IOC 容器對象
ConfigurableApplicationContextApplicationContext 的子接口,包含一些擴展方法 refresh() 和 close() ,讓 ApplicationContext 具有啟動、關閉和刷新上下文的能力。
WebApplicationContext專門為 Web 應用準備,基于 Web 環境創建 IOC 容器對象,并將對象引入存入 ServletContext 域中。

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

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

相關文章

如何從 Windows 11/10/8.1/8/7 恢復已刪除的視頻

意外刪除了視頻或格式化了 SD 卡/硬盤?沒有備份已刪除的視頻?別擔心,我們有解決方案來恢復 Windows 11、10 中已刪除的視頻并處理這種糟糕的情況。 但在了解如何恢復已刪除的視頻和視頻恢復應用程序之前,請知道 Windows 會為您提…

ARMv8寄存器詳解

文章目錄 一、ARMv8寄存器介紹二、通用寄存器三、 PSTAE寄存器四、特殊寄存器五、系統寄存器 一、ARMv8寄存器介紹 本文我來給大家介紹一下ARMv8的寄存器部分,ARMv8中有34個寄存器,包括31個通用寄存器、一個棧指針寄存器SP(X31),一個程序計數器寄存器PC…

Apache Drill 2萬字面試題及參考答案

目錄 什么是Apache Drill? Apache Drill的主要特點是什么? Apache Drill如何實現對復雜數據的查詢? 描述Apache Drill的數據存儲模型。 為什么Apache Drill被稱為自服務的SQL查詢引擎? Apache Drill支持哪些類型的數據源? 解釋Apache Drill中的“schema discovery”…

Transformer前置知識:Seq2Seq模型

Seq2Seq model Seq2Seq(Sequence to Sequence)模型是一類用于將一個序列轉換為另一個序列的深度學習模型,廣泛應用于自然語言處理(NLP)任務,如機器翻譯、文本摘要、對話生成等。Seq2Seq模型由編碼器&#…

《框架封裝 · 統一異常處理和返回值包裝》

📢 大家好,我是 【戰神劉玉棟】,有10多年的研發經驗,致力于前后端技術棧的知識沉淀和傳播。 💗 🌻 CSDN入駐不久,希望大家多多支持,后續會繼續提升文章質量,絕不濫竽充數…

貪心算法-以高校科研管理系統為例

1.貪心算法介紹 1.算法思路 貪心算法的基本思路是從問題的某一個初始解出發一步一步地進行,根據某個優化測度,每一 步都要確保能獲得局部最優解。每一步只考慮一 個數據,其選取應該滿足局部優化的條件。若下 一個數據和部分最優解連在一起…

JavaEE初階-網絡原理1

文章目錄 前言一、UDP報頭二、UDP校驗和2.1 CRC2.2 md5 前言 學習一個網絡協議,最主要就是學習的報文格式,對于UDP來說,應用層數據到達UDP之后,會給應用層數據報前面加上UDP報頭。 UDP數據報UDP包頭載荷 一、UDP報頭 如上圖UDP的…

Kubernetes(K8s) kubectl 常用命令

文章目錄 一、常用命令1.1 kubectl describe 命令 二、kubectl 命令中的簡寫三、Helm3.1 常用命令:3.2 遇到的問題3.2.1 cannot re-use a name that is still in use 四、Containerd 一、常用命令 檢查 k8s 各節點狀態,確保k8s集群各節點狀態正常&#x…

概率基礎——矩陣正態分布matrix normal distribution

矩陣正態分布-matrix normal distribution 定義性質應用 最近碰到了這個概念,記錄一下 矩陣正態分布是一種推廣的正態分布,它應用于矩陣形式的數據。矩陣正態分布在多維數據分析、貝葉斯統計和機器學習中有廣泛的應用。其定義和性質如下: 定…

Emacs之解決:java-mode占用C-c C-c問題(一百四十六)

簡介: CSDN博客專家,專注Android/Linux系統,分享多mic語音方案、音視頻、編解碼等技術,與大家一起成長! 優質專欄:Audio工程師進階系列【原創干貨持續更新中……】🚀 優質專欄:多媒…

【django項目使用easycython編譯】Cannot convert Unicode string to ‘str‘ implicitly.

django項目編譯遇到的問題 報錯條件 需要編譯的python源碼里面的函數寫了type hint,尤其是return的type hint, 當type hint是str時,但是變量確實f-string格式化后得到的,編譯時會報錯 報錯原因 easycython會檢查變量類型&…

軟件開發中的原型開發與需求文檔開發:哪個更優?

1. 引言 在軟件開發過程中,選擇合適的開發方法對于項目的成功至關重要。基于原型開發和基于需求文檔開發是兩種常見的開發方法,各自有其優點和缺點。在項目復雜性、客戶需求和資源限制等因素的影響下,開發團隊需要慎重選擇適合的開發方法。 …

C++語言相關的常見面試題目(二)

1.vector底層實現原理 以下是 std::vector 的一般底層實現原理: 內存分配:當創建一個 std::vector 對象時,會分配一塊初始大小的連續內存空間來存儲元素。這個大小通常會隨著 push_back() 操作而動態增加。 容量和大小:std::vec…

element-plus 的form表單組件之el-radio(單選按鈕組件)

單選按鈕組件適用于同一組類型的選項只能互斥選擇的場景,就是支持單選。單選組件包含以下3個組件 組件名作用el-radio-group單選組組件,子元素可以是el-radio或el-radio-button,v-mode綁定單選組的響應式屬性el-radio單選組件,la…

階段三:項目開發---搭建項目前后端系統基礎架構:任務9:導入空管基礎數據

任務描述 本階段任務是導入項目的基礎數據,包括空管基礎數據和離線的實時飛行數據(已經脫敏)。 任務指導 本階段任務需要導入兩種數據: 1、在MySQL中導入空管基礎數據 kongguan.sql空管基礎數據表說明: 1告警信息…

OpenCV直方圖計算函數calcHist的使用

操作系統:ubuntu22.04OpenCV版本:OpenCV4.9IDE:Visual Studio Code編程語言:C11 功能描述 圖像的直方圖是一種統計表示方法,用于展示圖像中不同像素強度(通常是灰度值或色彩強度)出現的頻率分布。具體來說…

對MsgPack與JSON進行序列化的效率比較

序列化是將對象轉換為字節流的過程,以便在內存或磁盤上存儲。常見的序列化方法包括MsgPack和JSON。以下將詳細探討MsgPack和JSON在序列化效率方面的差異。 1. MsgPack的效率: 優點: 高壓縮率: MsgPack采用高效的二進制編碼格式&…

Embedding理解

一、概念 Embedding 可以理解為一種將概念、物體或信息轉換為數字序列的數值表示方法。它是溝通兩個不同世界或領域的橋梁,能夠把各種類型的數據(如文本、圖像、視頻等)映射到一個向量空間中。 在這個向量空間里,相似的項目(例如語義上相近的單詞、相似的圖像或相關的視…

cs231n作業1——SVM

參考文章:cs231n assignment1——SVM SVM 訓練階段,我們的目的是為了得到合適的 𝑊 和 𝑏 ,為實現這一目的,我們需要引進損失函數,然后再通過梯度下降來訓練模型。 def svm_loss_naive(W, …

【Qt】Qt概述

目錄 一. 什么是Qt 二. Qt的優勢 三. Qt的應用場景 四. Qt行業發展方向 一. 什么是Qt Qt是一個跨平臺的C圖形用戶界面應用程序框架,為應用程序開發者提供了建立藝術級圖形界面所需的所有功能。 Qt是完全面向對象的,很容易擴展,同時Qt為開發…