【Spring】什么是Spring?

什么是Spring?

Spring是一個開源的輕量級框架,是為了簡化企業級開發而設計的。我們通常講的Spring一般指的是Spring Framework。Spring的核心是控制反轉(IoC-Inversion of Control)和面向切面編程(AOP-Aspect-Oriented Programming)。這些功能使得開發者可以專注于業務邏輯的實現,不用去關注底層的實現。除此之外,Spring還可以與第三方庫和框架集成,如Mybatis等,使得我們開發更加方便。

我們來看看官方的解釋:

Spring | Why Spring

可以看到,spring包含了很多模塊,簡單來說:Spring是包含了很多工具方法的IoC容器

什么是容器?

Spring容器是Spring框架中的核心組成部分,負責管理Spring Bean的生命周期和依賴關系,Spring容器是一個BeanFactory(Bean工廠),負責實例化、配置和管理Bean。

在Spring程序中,我們所有的Bean都是存放在容器中,通過IoC(控制反轉)技術進行管理。Spring容器通過自動裝配(autowiring)的方式將各個Bean之間建立聯系,從而減少手動配置的工作量。同時,Spring容器還提供了豐富的擴展機制,使得開發者可以根據自己的需求對bean進行定制化配置。

什么是IoC?

Spring IoC(控制反轉),是一種設計思想,通過將對象的創建和管理權交給了Spring容器降低了程序之間的耦合性,

在Spring框架中,IoC主要通過XML配置文件、注解或Java配置等方式實現。通過使用IoC,應用程序的各個模塊之間就可以以低耦合的形式進行協同工作,提高應用程序的可擴展性和可維護性。

傳統程序開發流程

我們來舉個例子,來更好的理解上面所述內容。

假設我們現在要生產一輛車,其基本思路如下:

按照傳統的做法,我們生產一輛車,車的構成需要依賴車身(Framework),而車身需要依賴底盤(Bottom),底盤需要依賴輪胎(Tire)。

按照這種思路,我們用代碼實現如下:

public class CarProduct {public static void main(String[] args) {Car car = new Car();car.init();}/*** 汽車對象*/static class Car {private Framework framework;public Car() {framework = new Framework();}public void init() {framework.init();}}/*** 車身Framework*/static class Framework {private Bottom bottom;public Framework() {bottom = new Bottom();}public void init() {bottom.init();}}/*** 底盤Bottom*/static class Bottom {private Tire tire;public Bottom() {tire = new Tire();}public void init() {tire.init();}}/*** 輪胎Tire*/static class Tire {private int size = 20;//輪胎大小public void init() {System.out.println("輪胎大小:" + size);}}
}

我們可以看到,在上面的代碼中,輪胎的尺寸是固定的,但是現在車的數量非常多,車輪胎的尺寸不可能都是一樣的,所以我們就需要生產出各種尺寸大小的輪胎。我們需要對上面的代碼進行修改:

public class CarProduct {public static void main(String[] args) {Car car = new Car();car.init(10);}/*** 汽車對象*/static class Car {private Framework framework;public Car() {framework = new Framework();}public void init(int size) {framework.init(size);}}/*** 車身Framework*/static class Framework {private Bottom bottom;public Framework() {bottom = new Bottom();}public void init(int size) {bottom.init(size);}}/*** 底盤Bottom*/static class Bottom {private Tire tire;public Bottom() {tire = new Tire();}public void init(int size) {tire.init(size);}}/*** 輪胎Tire*/static class Tire {public void init(int size) {System.out.println("輪胎大小:" + size);}}
}

我們可以看到,雖然滿足我們的需求了,但是在上面的代碼中,不難看到,當最底層的代碼修改后,整個調用鏈上的代碼都需要進行修改,這樣耦合度就非常高了。

那么如果解決上面出現的這種問題呢?

在上面的代碼中,我們都是在每個類中創建下一個要調用的類,這樣的耦合度就非常高。

那么我們可以不在類中創建下級類,而是改為傳遞的方式(即注入),這樣我們就能實現解耦,下級類的改變發生變化,對于當前類來說,也無需修改任何代碼。

解耦指的是:解決了代碼之間的依賴程度,也可以叫做程序相關性,好的程序的代碼的耦合性是很低的,也就是代碼之間要解耦

這就好比我們生產一輛汽車,如果所有的配件都是自己制造的,那么當客戶要改變需求時,如,客戶想要一個比較大的輪胎,那么我們就需要自己生產,這樣的效率是非常低的,但如果我們把輪胎的生產外包出去,那么就算輪胎的尺寸要發生改變,我們也能向代理公廠下單即可,無需自己生產,這樣效率就提高了不少。

控制反轉程序開發流程(IoC)

?根據上面所述,對代碼進行修改:

*** CarProduct類是汽車生產模型的示例,展示了如何通過組合不同類來構建復雜的對象結構*/
public class CarProduct {/*** 程序的入口點* 創建汽車對象及其組成部分,并初始化* @param args 命令行參數*/public static void main(String[] args) {// 創建輪胎對象,指定輪胎大小Tire tire = new Tire(20);// 創建底盤對象,包含上面創建的輪胎Bottom bottom = new Bottom(tire);// 創建車身對象,包含上面創建的底盤Framework framework = new Framework(bottom);// 創建汽車對象,包含上面創建的車身Car car = new Car(framework);// 初始化汽車對象car.init();}/*** 汽車對象*/static class Car {private Framework framework;/*** 構造方法,初始化汽車的車身* @param framework 汽車的車身*/public Car(Framework framework) {this.framework = framework;}/*** 初始化汽車對象,包括其車身*/public void init() {framework.init();}}/*** 車身Framework*/static class Framework {private Bottom bottom;/*** 構造方法,初始化車身的底盤* @param bottom 車身的底盤*/public Framework(Bottom bottom) {this.bottom = bottom;}/*** 初始化車身對象,包括其底盤*/public void init() {bottom.init();}}/*** 底盤Bottom*/static class Bottom {private Tire tire;/*** 構造方法,初始化底盤的輪胎* @param tire 底盤的輪胎*/public Bottom(Tire tire) {this.tire = tire;}/*** 初始化底盤對象,包括其輪胎*/public void init() {tire.init();}}/*** 輪胎Tire*/static class Tire {private int size;//輪胎大小/*** 構造方法,初始化輪胎的大小* @param size 輪胎的大小*/public Tire(int size) {this.size = size;}/*** 初始化輪胎對象,打印輪胎大小*/public void init() {System.out.println("輪胎大小:" + size);}}
}

我們可以看到,通過上面的修改,就算底層類發生變化,整個調用鏈的代碼也是不用做任何修改的,這樣就實現代碼之間的解耦,從而提高了代碼的靈活性、復用性。

我們來對比一下傳統程序開發流程和控制反轉程序開發流程:

我們可以看到,傳統的開發流程是:Car依賴Framework,Framework依賴Bottom,...。而在改進之后的代碼中,控制權發生了反轉,不再是由上級對象創建下級對象并控制下級對象,而是下級對象注入到上級對象中,下級對象不再受上級對象的控制,這樣就算下級對象發生改變,也不會影響到上級對象,這就是典型的控制反轉,也就是IoC的實現思想

?如何理解Spring IoC

在以往的程序設計中,對象之間的依賴關系通常是由程序內部通過new關鍵字來實現的,這樣的方式,會導致程序內部與具體實現的對象緊密聯系(即耦合度高),一旦對象的實現發生改變,那么對于程序中的一部分代碼也需要進行修改,這不僅增加了開發成本,而且也增加了代碼的維護難度。

Spring IoC則是將對象的創建和管理權交給了Spring容器。在Spring容器中,所有的對象稱為Bean,并通過配置文件或注解等方式來進行獲取對象。當程序某處需要用到Bean對象時,Spring容器就會負責查找、創建、注入Bean對象。而程序本身不需要關心Bean對象時如何實例化和管理的。這種方式的創建和管理權從原先的程序中轉移到Spring容器中,從而實現了控制反轉(IoC)。

Spring IoC的優點

  • 降低耦合度:通過把對象的實例和管理權交給Spring容器,從而讓程序與對象之間的耦合性降低,使得代碼更加靈活、可維護、可復用。
  • 提高可擴展性:由于對象的創建和管理權交給了Spring容器,當我們需要添加新的功能或模塊時,我們只需要在Spring中注冊相應的bean即可。
  • 簡化開發:使用Spring IoC可以簡化開發。開發者只需要關注業務邏輯的實現,而不需要花費過多的精力在對象的創建和管理上。
  • 提高性能:雖然使用Spring IoC會增加一些額外的開銷,但在大多數情況下,這種開銷是微不足道的。而且,通過使用Spring IoC,可以減少不必要的對象創建和銷毀,從而提高應用程序的性能。

DI(依賴注入)

DI(Dependcy Injection,即依賴注入)是一種軟件設計模式,用于實現松耦合和可測試性的代碼結構。在尋常的編程中,對象通常自己負責創建和管理它鎖依賴的其他對象,這樣導致了對象之間的耦合度高,使得對象難以復用和測試。

DI是一種實現控制反轉(Inversion of Control,簡稱 IoC)的機制。它允許對象之間的依賴關系由外部容器(Spring 容器)來管理,而不是由對象自身來創建或查找依賴對象。這種方式可以減少對象之間的耦合性,提高代碼的可重用性和可維護性

DI的實現方式

DI的主要實現方式包括構造函數注入、屬性注入和方法注入

  • 構造函數注入是最常見的DI方式,它通過在對象的構造函數中傳遞依賴對象來實現。
  • 屬性注入是通過設置對象的屬性來注入依賴對象。
  • 方法注入是一種更靈活的DI方式,它通過在對象的方法中傳遞依賴對象來實現。

DI的優點

  • 降低耦合度DI使得對象之間的耦合度降低,因為對象不直接創建依賴,而是通過外部注入的方式獲得。這使得每個對象更加獨立,更易于管理和維護。
  • 提高代碼的可維護性:由于對象之間的耦合度降低,修改一個對象時對其他對象的影響也會減少,這使得代碼更易于維護和升級。
  • 提高靈活性:DI使得對象的依賴關系可以動態地管理和修改,這使得代碼更加靈活,可以根據實際需求進行修改和擴展。
  • 增強代碼的可測試性:依賴注入使得單元測試變得更加容易。開發者可以通過注入模擬(mock)對象或存根(stub)來測試組件的行為,而不需要依賴于實際的依賴對象。
  • 提高代碼的可重用性:由于對象不依賴于具體的實現,而是依賴于抽象(接口或抽象類),因此可以更容易地替換對象的實現,從而提高代碼的可重用性。

Spring相關網站

Spring官方網站:Spring | Homehttps://spring.io/https://spring.io/https://spring.io/
Spring Framework官方文檔:Spring Framework 文檔 :: Spring Frameworkhttps://docs.spring.io/spring-framework/reference/https://docs.spring.io/spring-framework/reference/https://docs.spring.io/spring-framework/reference/
Spring Boot官方文檔:Spring Boot :: Spring Boothttps://docs.spring.io/spring-boot/index.htmlhttps://docs.spring.io/spring-boot/index.htmlhttps://docs.spring.io/spring-boot/index.html
Spring Cloud官方文檔:Spring Cloudhttps://spring.io/projects/spring-cloud#learnhttps://spring.io/projects/spring-cloud#learnhttps://spring.io/projects/spring-cloud#learn
Spring源代碼倉庫:Spring · GitHubhttps://github.com/spring-projectshttps://github.com/spring-projectshttps://github.com/spring-projects
Spring源代碼倉庫中文文檔:Spring Framework 中文文檔https://www.docs4dev.com/docs/zh/spring-framework/5.1.3.RELEASE/reference/https://www.docs4dev.com/docs/zh/spring-framework/5.1.3.RELEASE/reference/https://www.docs4dev.com/docs/zh/spring-framework/5.1.3.RELEASE/reference/
Spring Boot中文文檔:Spring Boot 參考https://www.docs4dev.com/docs/spring-boot/2.4.6/reference/getting-started.html#getting-startedhttps://www.docs4dev.com/docs/spring-boot/2.4.6/reference/getting-started.html#getting-startedhttps://www.docs4dev.com/docs/spring-boot/2.4.6/reference/getting-started.html#getting-started
Spring Cloud中文文檔:Spring Cloud 中文文檔https://www.docs4dev.com/docs/zh/spring-cloud/Finchley.SR2/reference/https://www.docs4dev.com/docs/zh/spring-cloud/Finchley.SR2/reference/https://www.docs4dev.com/docs/zh/spring-cloud/Finchley.SR2/reference/


以上就是本篇所有內容啦~

若有不足,歡迎指正~

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

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

相關文章

學習筆記:機器學習中的數學原理(一)

1. 集合 集合分為有限集和無限集; 對于有限集,兩集合元素數相等即為等勢; 對于無限集,兩集合元素存在一一映射關系即為等勢; 無限集根據是否與正整數集等勢分為可數集和不可數集。 2. sigmoid函數(也叫…

【信息系統項目管理師-案例真題】2016下半年案例分析答案和詳解

更多內容請見: 備考信息系統項目管理師-專欄介紹和目錄 文章目錄 試題一【問題1】4 分【問題2】12 分【問題3】3 分【問題4】6 分試題二【問題1】3 分【問題2】4 分【問題3】8 分【問題4】5 分【問題5】5 分試題三【問題1】4 分【問題2】8 分【問題3】5 分【問題4】8 分試題一…

基于javaweb的SpringBoothis智能醫院管理系統(源碼+文檔+部署講解)

🎬 秋野醬:《個人主頁》 🔥 個人專欄:《Java專欄》《Python專欄》 ??心若有所向往,何懼道阻且長 文章目錄 運行環境開發工具適用功能說明一、項目運行 環境配置: 運行環境 Java≥8、MySQL≥5.7、Node.js≥14 開發工具 后端&…

JS實現燈光閃爍效果

在 JS中&#xff0c;我們可以實現燈光閃爍效果&#xff0c;這里主要用 setInterval 和 clearInterval 兩個重要方法。 效果圖 源代碼 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>燈閃爍效果<…

Linux ltrace跟蹤入門

文章目錄 背景ltrace原理ltrace使用跟蹤程序調用庫函數跟蹤指定pid進程調用 參考 本文介紹ltrace跟蹤 背景 ltrace 會攔截并記錄正在執行的進程所調用的動態庫調用以及該進程接收到的信號&#xff0c;它還可以攔截并打印程序執行的系統調用。 其代碼位置在&#xff1a;https:/…

PCA9685 16路PWM 控制板 STM32F103 驅動

PCA9685 擁有16路PWM&#xff0c;通過 IIC 與 STM32 進行通信&#xff0c;以下驅動代碼已通過測試&#xff0c;你可以進行更多代碼優化 #include "pca9685.h"// 向 PCA9685 寫入一個字節數據 static void PCA9685_write8( uint8_t addr, uint8_t d) {while (I2C_Get…

使用 Apache Spark 進行大數據分析

使用 Apache Spark 進行大數據分析 環境準備 為了能夠在本地環境中運行Spark程序&#xff0c;需要先完成環境搭建。確保已經安裝了Jupyter Notebook和Apache Spark&#xff0c;并完成了兩者之間的集成。 創建 SparkSession 在 Python 中使用 PySpark 時&#xff0c;通常會創…

2025 專業的物聯網軟件開發公司有哪些

物聯網&#xff08;Internet of Things&#xff0c;簡稱IoT&#xff09;具有多個顯著的優勢&#xff0c;主要包括提高效率、節省成本、數據收集與分析、自動化控制、改善用戶體驗、增強決策能力和創新業務模式?。2025&#xff0c;有哪些比較專業的物聯網開發公司呢&#xff1f…

7.PPT:“中國夢”學習實踐活動【20】

目錄 NO1234? NO5678? NO9\10\11 NO1234 考生文件夾下創建一個名為“PPT.pptx”的新演示文稿Word素材文檔的文字&#xff1a;復制/挪動→“PPT.pptx”的新演示文稿&#xff08;藍色、黑色、紅色&#xff09; 視圖→幻燈片母版→重命名&#xff1a;“中國夢母版1”→背景樣…

學習筆記十九:K8S生成pod過程

K8S生成pod過程 流程圖具體生成過程用戶提交 Pod 定義API Server 處理請求調度器分配節點&#xff08;Scheduling&#xff09;目標節點上的 Pod 創建網絡配置狀態上報與監控控制器管理&#xff08;Controller Manager&#xff09;就緒與服務發現 關鍵錯誤場景高級特性 流程圖 具…

封裝descriptions組件,描述,靈活

效果 1、組件1&#xff0c;dade-descriptions.vue <template><table><tbody><slot></slot></tbody> </table> </template><script> </script><style scoped>table {width: 100%;border-collapse: coll…

21.2.6 字體和邊框

版權聲明&#xff1a;本文為博主原創文章&#xff0c;轉載請在顯著位置標明本文出處以及作者網名&#xff0c;未經作者允許不得用于商業目的。 通過設置Rang.Font對象的幾個成員就可以修改字體&#xff0c;設置Range.Borders就可以修改邊框樣式。 【例 21.6】【項目&#xff…

FPGA VGA timing

概念 VGA(Video Graphics Array)時序是控制VGA接口顯示圖像的關鍵參數,它主要包括行時序和場時序兩部分。以下是對VGA時序的詳細解釋: 一、VGA接口簡介 VGA接口是IBM公司在1987年推出的一種使用模擬信號的視頻傳輸標準,具有成本低、結構簡單、應用靈活等優點,至今仍被廣…

中級通信工程師綜合教材(5、6章節)

五、現代通信網 1、通信網的構成要素 通信網在硬件設備方面的構成要素是交換設備、傳輸鏈路和終設備。 構成要素 功能作用 常見設備舉例 終端設備 通信的源點和目的地 電話機、傳真機、計算機、視頻終端、多媒體終端等 交換設備 通信網的核心設備,主要完成呼叫處理、信令處理…

360手機刷機 360手機解Bootloader 360手機ROOT

360手機刷機 360手機解Bootloader 360手機ROOT 問&#xff1a;360手機已停產&#xff0c;現在和以后&#xff0c;能刷機嗎&#xff1f; 答&#xff1a;360手機&#xff0c;是肯定能刷機的 360手機資源下載網站 360手機-360手機刷機RootTwrp 360os.top 360rom.github.io 一、…

.net一些知識點5

1.dot Net帶out的參數如何使用 string name;//假設這個參數帶out TestMethod(1,out name);//一定要有out 方法體中&#xff0c;一定要有out參數的賦值&#xff0c;并且能輸出 2.參數的傳遞方式有哪些 a.值傳遞 b.引用傳遞 ref c.輸出傳遞 out 3.設計模式知道哪些 3.us…

鏈表專題-02

鏈表專題 /*** 鏈表的節點* param <E>*/ public class ListNode<E> {public E element;public ListNode<E> next;public ListNode() {}public ListNode(E element) {this.element element;}public ListNode(E element, ListNode<E> next) {this.eleme…

外部中斷實驗 #STM32F407

外部中斷實驗 此實驗將外部中斷配置為按鍵輸入&#xff0c;通過按鍵輸入觸發外部中斷&#xff0c;在外部中斷里面實施相應的處理&#xff0c;具體功能&#xff1a; 按下KEY0&#xff0c;翻轉LED0狀態按下KEY1&#xff0c;翻轉LED1狀態按下KEY2&#xff0c;同時翻轉LED0和LED1…

java中如何給內部類的屬性賦值

在 Java 中&#xff0c;內部類的屬性賦值方式取決于該屬性的訪問修飾符、內部類的類型&#xff08;非靜態或靜態&#xff09;&#xff0c;以及賦值的時機。以下是幾種常見的方式&#xff1a; 1. 通過構造方法賦值 class Outer {class Inner {private String name;// 構造方法賦…

機器學習8-卷積和卷積核1

機器學習8-卷積和卷積核1 卷積與圖像去噪卷積的定義與性質定義性質卷積的原理卷積步驟卷積的示例與應用卷積的優缺點優點缺點 總結 高斯卷積核卷積核尺寸的設置依據任務類型考慮數據特性實驗與調優 高斯函數標準差的設置依據平滑需求結合卷積核尺寸實際應用場景 總結 圖像噪聲與…