爲什麼學習Spring,什麼是Spring,什麼是IOC,什麼是DI,什麼是容器

1.前言

第一次接觸spring框架時,概念裏它是一個很人性化的Web容器,通常只需要配置bean文件以及數據源,一個demo就能很順利的跑起來,確實節省了很多代碼,可以把更多的精力放在業務邏輯上,但是並不知道其博大精深之處,但凡看到什麼設計模式、依賴倒置、控制反轉、面向切面,就覺得很費解,很多書一上來就把控制反轉的文字概念搬上來,甚至沒有舉例,讓人無所適從。直到前段時間看了一些源碼,重拾設計模式,纔有點恍然大悟,原來沒有那麼難理解,當初只是被一些高深的文字唬住了,說這麼多不就是爲了解耦嘛。

2.什麼是IOC

IoC不是一種技術,只是一種思想,一個重要的面向對象編程的法則,它能指導我們如何設計出松耦合、更優良的程序。傳統應用程序都是由我們在類內部主動創建依賴對象,從而導致類與類之間高耦合,難於測試;有了IoC容器後,把創建和查找依賴對象的控制權交給了容器,由容器進行注入組合對象,所以對象與對象之間是鬆散耦合,這樣也方便測試,利於功能複用,更重要的是使得程序的整個體系結構變得非常靈活。

3.什麼是DI

IoC的一個重點是在系統運行中,動態的向某個對象提供它所需要的其他對象。這一點是通過DI(Dependency Injection,依賴注入)來實現的,DI是組件之間依賴關係由容器在運行期決定,形象的說,即由容器動態的將某個依賴關係注入到組件之中。依賴注入的目的並非爲軟件系統帶來更多功能,而是爲了提升組件重用的頻率,併爲系統搭建一個靈活、可擴展的平臺。通過依賴注入機制,我們只需要通過簡單的配置,而無需任何代碼就可指定目標需要的資源,完成自身的業務邏輯,而不需要關心具體的資源來自何處,由誰實現。## 附錄

4.IOC和DI的關係

按照我的理解,其實它們是同一個概念的不同角度描述,控制反轉概念比較含糊(可能只是理解爲容器控制對象這一個層面,很難讓人想到誰來維護對象關係),而DI“依賴注入”明確描述了“被注入對象依賴IoC容器配置依賴對象”。所以在討論時我更喜歡用DI而不是IOC來介紹spring

5.什麼是容器

通過前面的描述,我們知道了IOC和DI的作用就是爲了解決程序耦合,具體怎麼解決請看文章的附錄,其具體過程大概就是:

我們可以把三層的對象都使用配置文件配置起來,當啓動服務器應用加載的時候,讓一個類中的方法通過讀取配置文件,把這些對象創建出來並存起來。在接下來的使用的時候,直接拿過來用就好了。那麼,這個讀取配置文件,創建和獲取三層對象的類就是工廠。

那麼這些讀取到的對象應該存放在什麼地方?由於我們是很多對象,肯定要找個集合來存。這時候有 Map 和 List 供選擇。
到底選 Map 還是 List 就看我們有沒有查找需求。有查找需求,選 Map。所以我們的答案就是在應用加載時,創建一個 Map,用於存放三層對象。我們把這個 map 稱之爲容器,spring IOC/DI的更爲直觀的叫法是容器,這是因爲spring可以管理很多類,當需要某一類對象的實例時,spring就會提供相應的實例,就像是一個容器裏面,所以我們經常說IOC容器

6.附錄

程序耦合:

現在有KnightQuest騎士和探險兩個接口,RescueQuest實現了Quest接口,它只能進行拯救任務

public class BraveKnight implements Knight{
	private RescueQuest quest;
	public BraveKnight (){
		this.quest = new RescueQuest ();
	}
	public void actionOnQuest(){
		quest.action();
	}
}

可以看到,BraveKnight 在它的構造函數中自行創建了RescueQuest對象,這使得這兩個對象高度耦合,而且這個騎士類的功能也受到限制,只能執行拯救任務,如果有其他探險比如殺掉一條龍這裏不能完成,更糟糕的是在單元測試中必須當保證騎士的actionOnQuest()被調用的時候,探險類的action()也要被執行,這將導致代碼難以測試,難以複用,一個地方出現Bug,將會導致更多地方出現bug
如何解耦
通過工廠模式解耦:
在傳統的獲取對象的方式是通過new來獲取對象,是主動的獲取
在這裏插入圖片描述
現在我們獲取對象時,同時跟工廠要,有工廠爲我們查找或者創建對象。是被動的。
在這裏插入圖片描述
這種被動接收的方式獲取對象的思想就是控制反轉,它是 spring 框架的核心之一,那麼什麼是控制反轉呢:

控制反轉(Inversion of Control簡寫爲IoC)

概念:

  • 控制反轉(Inversion of Control簡寫爲IoC,把對象的創建交給框架,它包括依賴注入和依賴查找,它的作用是降低程序間的耦合(依賴關係)

依賴注入:
**依賴注入(Dependency Injection,簡稱DI)**它的作用就是讓對象之間保持鬆散耦合,具體實現由spring容器提供,在傳統開發中:一個類中包含其他類的對象,比如BraveKnight 類中的RescueQuest對象,騎士依賴探險,它們之間的關係被稱爲依賴關係BraveKnight負責管理與自己相互協作的對象的引用RescueQuest quest,這會導致程序的高度耦合

我們知道了可以通過工廠模式機型解耦,在Spring中,對象的依賴關係通過依賴注入(DI)由系統中負責協調各對象的第三方組件在創建對象的時候進行設定,這裏的第三方組件就是我們所說的工廠,在spring中的體現爲Spring容器

在這裏插入圖片描述
如圖所示,依賴注入會將所依賴的關係自動交給目標對象,而不是讓對象自己去獲取依賴,依賴關係將被自動注入到他們的對象中去
下面我們通過一個案例來了解一下具體的執行過程:

/**
*探險類接口
*/
public interface Quest {
    public void action();
}
/*
*騎士接口
*/
public interface Knight { }
/**
*	騎士類
*/
public class BraveKnight implements Knight {

    private Quest quest;

    public BraveKnight(Quest quest) {
        this.quest = quest;
    }

    public void actionOnQuest(){
        quest.action();
    }
}
/**
*探險類
*/
public class RescueQuest implements Quest {
    public void action() {
        System.out.println("執行拯救任務");
    }
}

我們改動了BraveKnight的結構,將quest的實現通過構造器的方式實現注入,只要實現了Quest接口都可以傳進來,這就保證了騎士可以完成不同的探險任務
在這裏插入圖片描述
除了XML進行配置還可以基於java的配置,在這裏不予演示
通過上述代碼我們就可以回答之前的問題:爲什麼會簡化開發,
spring還有其他簡化開發的方式,這裏只介紹了IoC依賴注入來展示

Spring的體系結構:

在這裏插入圖片描述
讓我們分別瀏覽這些模塊

  • Spring核心容器
    容器是Spring框架最核心的部分,它管理着Spring應用中bean的創建,配置和管理,在該模塊中包括了Spring bean工廠,它爲Spring提供了DI功能,基於bean工廠我們還會發現有多種Spring上下文實現的方式,每一種都提供了配置Spring的不同方式
  • SpringAOP模塊
    面向切面編程
  • 數據訪問與集成
    有不同的方式實現,可以是Spring Data JPA或Mybatis或其他ORM,也可以是Spring中的JDBC模板
  • Web與遠程調用
    MVC模式是一種被普遍接受的構建web應用的方法,如當前流行的springmvc框架

當我們具體的開發一個企業級Java應用時,這些模塊都會提供我們所需要的一切,我們只需要在pom文件中導入需要的座標即可,我們可以根據需求自主搭配相應的模塊而不是將整個應用完全建立在Spring框架之上,比如數據訪問與集成,可以用Spring來整合其他的框架比如Mybatis而不是Spring提供的Spring Data了
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章