欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring框架概述及核心設(shè)計思想分享

 更新時間:2025年02月18日 15:19:42   作者:韻秋梧桐  
Spring框架是一種開源的Java企業(yè)級應(yīng)用開發(fā)框架,提供了IoC(控制反轉(zhuǎn))容器和DI(依賴注入)等核心設(shè)計思想,SpringBoot則是在Spring基礎(chǔ)上進一步簡化配置,提供了快速開發(fā)、內(nèi)置服務(wù)器等功能,學(xué)習Spring框架需要掌握容器、IoC和DI等概念,以及分層設(shè)計等軟件工程思想

一. Spring框架概述

1. 什么是Spring框架

我們通常所說的 Spring 指的是 Spring Framework(Spring 框架),它是?個開源框架,有著活躍而龐大的社區(qū),這就是它之所以能長久不衰的原因;Spring 支持廣泛的應(yīng)用場景,它可以讓 Java 企業(yè)級的應(yīng)用程序開發(fā)起來更簡單。

用?句話概括 Spring:Spring 框架是包含了眾多工具方法的 IoC 容器。

2. 為什么要學(xué)習框架?

因為學(xué)習框架相當于從“小作坊”到“工廠”的升級,小作坊什么都要自己做,工廠是組件式裝配,特點就是高效。

框架更加易?、簡單且高效。

Servlet有以下痛點:

  1. 添加外部 jar 不?便,容易出錯,比如添加了?個不匹配的外部 jar 版本。
  2. 運行和調(diào)試的時候需要配置 Tomcat 不?便。
  3. 發(fā)布不方便,Servlet 項目必須依靠外置的 Tomcat(外置的 Web 容器)運行。
  4. 路由配置不方便,?個訪問地址對應(yīng)?個 Servlet 類。

而 Spring Boot 相比于 Servlet 具備以下優(yōu)點:

  1. 快速添加外部 jar 包。
  2. 調(diào)試項目更方便,無需配置 Tomcat,點擊“運行”按鈕就可以直接運行項目,因為 Spring Boot 內(nèi)置了 Tomcat 容器可直接運行,但是 Servlet 需外掛 Tomcat。
  3. 發(fā)布項目更加方便,無需配置 Tomcat,使用 java -jar 方式就可以發(fā)布。
  4. 對象自動裝配。
  5. 添加路由更加方便,無需每個訪問地址都添加?個類。

3. Spring框架學(xué)習的難點

  1. 配置比較多。
  2. 需要?量的外部 jar 包,在下載時容易出錯。
  3. 會涉及簡單的軟件?程的設(shè)計思想(分層思想:前后端的分層思想;后端工程的分層思想)。
  4. 知識點相對來說比之前的知識更加的分散,要仔細聽才能搞懂各個知識點的邏輯關(guān)系。
  5. 要記的東西很多,所以要大量地重復(fù)練習才能記住,比如各種注解。

Spring框架基本學(xué)習應(yīng)用路線:Spring全家桶(Spring/Spring Boot/Spring MVC) -> MyBatis -> Redis 等。

二. Spring核心設(shè)計思想

Spring 核心就是這么一句話:Spring 框架是包含了眾多工具方法的 IoC 容器。

那么這句話怎么理解呢?什么是容器?什么又是 IoC?

1. 容器是什么?

容器是用來容納某種物品的(基本)裝置。 ——來?:百度百科

Java 中也有一些容器,比如 List,Map,Set 等這些集合,是屬于數(shù)據(jù)儲存的容器,它把我們常用的操作都封裝到集合中了,我們只需要知道集合為我們提供的方法就可以使用各種集合了;還有 Tomcat 是屬于 Web 容器,同理 Spring 是就一個 IoC 容器,它包含了許多的工具和方法。

2. IoC是什么?

IoC 即 Inversion of Control,直譯過來就是控制反轉(zhuǎn)的意思,這是一種思想,控制權(quán)反轉(zhuǎn),在 Java 的常規(guī)代碼中,對象的生命周期,是由當前代碼(程序員自己)控制的,而控制權(quán)反轉(zhuǎn)就是對象的生命周期,不再由當前代碼片段來控制,而是由 Spring(IoC 容器)來控制 。

這種思想還比較抽象,我們來通過一個例子來了解它。

我們都知道汽車,它包含輪胎,底座,車身等,現(xiàn)在我們要造一輛汽車時,需要有車身,而車身需要有底座和輪胎,最傳統(tǒng)的思想就是造車時,需要車身,于是就new一個車身,而車身需要底座,于是就再new一個底座,同理底座需要輪胎,那就造底座前new一個輪胎。

我們可以得到以下代碼:

package old;

/**
 * 傳統(tǒng)開發(fā)方式, 耦合性問題
 */
// 汽車類
public class Car {
    // 車身
    private Framework framework;

    public Car() {
        framework = new Framework();
    }

    public void init() {
        System.out.println("do car");
        // 汽車的組建依賴于車身
        framework.init();
    }
}

package old;

// 車身類
public class Framework {
    private Bottom bottom;

    public Framework() {
        bottom = new Bottom();
    }

    public void init() {
        System.out.println("do framework");
        // 車身的組建依賴于底盤
        bottom.init();
    }
}

package old;

// 底盤類
public class Bottom {
    private Tire tire;

    public Bottom() {
        tire = new Tire();
    }

    public void init() {
        System.out.println("do bottom");
        // 底盤的組建依賴于輪胎
        tire.init();
    }
}

package old;

// 輪胎類
public class Tire {
    private int size = 17; // 輪胎的尺寸
    public void init() {
        System.out.println("size -> " + size);
    }
}

package old;

public class Test {
    public static void main(String[] args) {
        Car car = new Car();
        car.init();
    }
}

但是,但上面的代碼中,輪胎的大小是固定寫死的, 然而隨著對的車的需求量越來越大,個性化需求也會越來越多,這 時候我們就需要加?多種尺寸的輪胎,那這個時候就要對上面的程序進行修改了,根據(jù)我們上面寫的代碼,我們需要往輪胎Tire類的構(gòu)造方法加上一個參數(shù),由于底盤Bottom類控制著Tire類,那么底盤類的構(gòu)造方法也需要加上一個參數(shù),以此類推,我們的車身Framework類與汽車Car類都需要為構(gòu)造方法加上參數(shù),于是我們得到了如下的代碼:

package old;

/**
 * 傳統(tǒng)開發(fā)方式, 耦合性問題
 */
// 汽車類
public class Car {
    // 車身
    private Framework framework;

    public Car(int size) {
        framework = new Framework(size);
    }

    public void init() {
        System.out.println("do car");
        // 汽車的組建依賴于車身
        framework.init();
    }
}

package old;

// 車身類
public class Framework {
    private Bottom bottom;

    public Framework(int size) {
        bottom = new Bottom(size);
    }

    public void init() {
        System.out.println("do framework");
        // 車身的組建依賴于底盤
        bottom.init();
    }
}

package old;

// 底盤類
public class Bottom {
    private Tire tire;

    public Bottom(int size) {
        tire = new Tire(size);
    }

    public void init() {
        System.out.println("do bottom");
        // 底盤的組建依賴于輪胎
        tire.init();
    }
}

package old;

// 輪胎類
public class Tire {
    private int size = 17; // 輪胎的尺寸

    public Tire(int size) {
        this.size = size;
    }

    public void init() {
        System.out.println("size -> " + size);
    }
}

package old;

public class Test {
    public static void main(String[] args) {
        Car car = new Car(20);
        car.init();
    }
}

此時,如果需要個性化定制輪胎的大小,就可以只改動構(gòu)造Car對象傳入的參數(shù)就可以了;但是,如果再加上加上一個需求,還要定制輪胎的顏色,那我們又要加參數(shù),此時就意味著像上面一樣修改最底層的代碼, 整個調(diào)?鏈上的所有代碼都需要修改。

這樣的代碼耦合性就太高了,為了解決這個問題,我們可以使用loC的思想來實現(xiàn)代碼,將控制權(quán)交出去,也就是說,IoC模式下,我們不再自己構(gòu)造創(chuàng)建對象,當我們需要輪胎Tire類時,你就給我傳一個Tire對象,我們不去new一個Tire對象了,這樣的話,就算在Tire類加參數(shù)也只需要改動Tire類的構(gòu)造方法與相關(guān)執(zhí)行方法與屬性,頂多再改一下Tire對象的創(chuàng)建,同理其他類也一樣,將對象作為參數(shù)傳入到上級類的構(gòu)造方法中去就行了,但此時其他類是不需要修改的,這個過程也叫做傳入或注入。

由于我們創(chuàng)建Car時需要Framework,所以先要實例一個Framework對象,同理實例一個Framework對象需要Bottom對象,那么需先實例一個Bottom對象,一樣,在實例Bottom對象之前需要實例一個Tire對象,于是需要先后創(chuàng)建Tire對象,Bottom對象,Framework對象后才能創(chuàng)建一個Car對象,我們可以得到如下的代碼:

package ioc;

public class Car {
    // 汽車的組建依賴于車身的組建
    private Framework franmework;

    public Car(Framework franmework) {
        this.franmework = franmework;
    }
    public void init() {
        System.out.println("do car...");
        franmework.init();
    }
}

package ioc;

public class Framework {
    // 車身的組建依賴于底盤
    private Bottom bottom;

    public Framework(Bottom bottom) {
        this.bottom = bottom;
    }
    public void init() {
        System.out.println("do franmework");
        bottom.init();
    }
}

package ioc;

public class Bottom {
    // 底盤的組建依賴于輪胎
    private Tire tire;

    public Bottom(Tire tire) {
        this.tire = tire;
    }

    public void init() {
        System.out.println("do bottom...");
        tire.init();
    }
}

package ioc;

public class Tire {
    private int size = 17;
    private String color = "黑色";

    public Tire(int size, String color) {
        this.size = size;
        this.color = color;
    }

    public void init() {
        System.out.println("size -> " + size);
        System.out.println("color->" + color);
    }
}

package ioc;

public class IOCDemo {
    // 這里的內(nèi)容包含就相當于是 IoC 容器做的事情
    // 對象的生命周期控制權(quán)就翻轉(zhuǎn)給 IoC 容器了, 不再由程序員控制
    private Tire tire;
    private Bottom bottom;
    private Framework framework;
    public Car car;
    public IOCDemo() {
        tire = new Tire(17, "紅色");
        bottom = new Bottom(tire);
        framework = new Framework(bottom);
        car = new Car(framework);
    }
}

package ioc;

/**
 * 模擬 IoC 容器
 */
public class Test {
    public static void main(String[] args) {
        // 直接使用, 創(chuàng)建就交給IoC了
        IOCDemo ioc = new IOCDemo();
        Car car = ioc.car;
        car.init();
    }
}

此時如果要變需求,需要加參數(shù)或減少參數(shù),IoC 的代碼只需改動圖中的兩處代碼即可, 整個調(diào)用鏈是不用做任何改變的, 達到了解耦的目的。

  • 在傳統(tǒng)的代碼中對象創(chuàng)建順序是:Car -> Framework -> Bottom -> Tire
  • 改進之后解耦的代碼的對象創(chuàng)建順序是:Tire -> Bottom -> Framework -> Car

到這里我們就可以發(fā)現(xiàn),傳統(tǒng)的代碼類創(chuàng)建順序是反著的,Car 控制 FrameWork,F(xiàn)rameWork 控制著 Bottom,Bottom 控制著 Tire;而改進之后的控制權(quán)發(fā)生了反轉(zhuǎn),是下層將對象注入到當前對象當中,下級的控制權(quán)不再由上級控制了,下級在發(fā)生改變時會將改變完成后的對象注入上級,這樣上級就是不受影響的,這就是 IoC 的實現(xiàn)思想。

所以 IoC 有以下的優(yōu)點:對象(Bean)的生命周期交給 IoC 框架維護,作為程序員無需關(guān)注,說白了就是程序員不需要關(guān)注對象創(chuàng)建、銷毀時機以及對象的依賴關(guān)系,這些工作加個 IoC 框架(也就是 Spring)做就行,實現(xiàn)了代碼的解耦,對象的使用更加方便高效。

3. Spring是IoC容器

Spring 框架就是包含了多個工具方法的 IoC 容器,既然是容器,那它就有存和取的功能,這也是 Spring 最核心的兩個功能:

  1. 將 Bean(對象)存儲到 Spring 容器中。
  2. 將 Bean(對象)從 Spring 容器中取出來。

將對象存放到容器有什么好處呢?

將對象存儲到 IoC 容器相當于我們將所有可能用到的工具制作好都放到倉庫,當我們需要使用時直接取即可,用完歸還倉庫;而 new 對象的方式相當于我們每次需要用工具的時候現(xiàn)場制作,制作完了扔掉,下次需要的時候重新做。

Spring 是?個 IoC 容器,說的是對象的創(chuàng)建和銷毀的權(quán)利都交給 Spring 來管理了,它本身?具備了存儲對象和獲取對象的能力。

4. DI(依賴注入)

DI,即Dependency Injection,依賴注入。

所謂依賴注?,就是由 IoC 容器在運行期間,動態(tài)地將某種依賴關(guān)系注入到對象之中,在pom.xml有一個依賴項,就是用來導(dǎo)入外部的資源,而這里的依賴注入,導(dǎo)入的不是外部的資源,而是對象;當某個 Java 實例需要另一個 Java 實例時,創(chuàng)建被調(diào)用者的工作不是由調(diào)用者實現(xiàn),而是由 Spring 容器來完成,然后注入調(diào)用者,因此稱為依賴注入。

IoC 與 DI 的區(qū)別是什么?

依賴注入(DI)和控制反轉(zhuǎn)(IoC)是從不同的角度的描述的同?件事情,就是指通過引入 IoC 容器,利用依賴關(guān)系注入的方式,實現(xiàn)對象之間的解耦。

IoC 是“目標”也是?種思想,而目標和思想只是?種指導(dǎo)原則,最終還是要有可行的落地方案,而 DI 就屬于具體的實現(xiàn);也就是說,IoC 是一種思想,而 DI 是 IoC 的一種實現(xiàn)。

5. DL(依賴查找)

DL,即Dependency Lookup,依賴查找,也是 IoC的一種實現(xiàn)。

依賴查找和依賴注入的區(qū)別在于,依賴注入是將依賴關(guān)系委托給容器,由容器來管理對象之間的依賴關(guān)系,容器外部是不關(guān)心這種依賴關(guān)系的,需要時由容器判斷提供什么;而依賴查找是由對象自己來查找它所依賴的對象,容器只負責管理對象的生命周期,也就是說此時需要容器外部自己確定要容器提供哪種依賴關(guān)系;兩者之間是主動和被動的區(qū)別。

總結(jié)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • spring cloud 配置中心native配置方式

    spring cloud 配置中心native配置方式

    這篇文章主要介紹了spring cloud 配置中心native配置方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • java 讀取文件方法的總結(jié)

    java 讀取文件方法的總結(jié)

    這篇文章主要介紹了java 讀取文件方法的總結(jié)的相關(guān)資料,這里提供文件讀取5種方法并附實例,需要的朋友可以參考下
    2017-08-08
  • Java添加Word文本水印和圖片水印

    Java添加Word文本水印和圖片水印

    這篇文章主要介紹了Java添加Word文本水印和圖片水印,文章圖文講解的很清晰,有對于這方面不懂得同學(xué)可以學(xué)習下
    2021-02-02
  • Java設(shè)計模塊系列之書店管理系統(tǒng)單機版(一)

    Java設(shè)計模塊系列之書店管理系統(tǒng)單機版(一)

    這篇文章主要為大家詳細介紹了Java單機版的書店管理系統(tǒng)設(shè)計模塊和思想第一章,感興趣的小伙伴們可以參考一下
    2016-08-08
  • 深入了解SpringBoot中@InitBinder注解的使用

    深入了解SpringBoot中@InitBinder注解的使用

    這篇文章主要介紹了深入了解SpringBoot中@InitBinder注解的使用,@InitBinder注解可以作用在被@Controller注解的類的方法上,表示為當前控制器注冊一個屬性編輯器,用于對WebDataBinder進行初始化,且只對當前的Controller有效,需要的朋友可以參考下
    2023-10-10
  • Java設(shè)計模式中的裝飾者模式

    Java設(shè)計模式中的裝飾者模式

    這篇文章主要介紹了Java設(shè)計模式中的裝飾者模式,裝飾者模式即Decorator?Pattern,裝飾模式是在不必改變原類文件和使用繼承的情況下,動態(tài)地擴展一個對象的功能
    2022-07-07
  • SpringBoot整合EasyCaptcha實現(xiàn)圖形驗證碼功能

    SpringBoot整合EasyCaptcha實現(xiàn)圖形驗證碼功能

    這篇文章主要介紹了SpringBoot整合EasyCaptcha實現(xiàn)圖形驗證碼功能,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2024-02-02
  • IDEA中Javaweb項目圖片加載不出來解決方案

    IDEA中Javaweb項目圖片加載不出來解決方案

    在IDEA中能夠正常的預(yù)覽到圖片,但是在生成項目的war包時,項目的目錄結(jié)構(gòu)卻會發(fā)生變化,所以無法訪問圖片,本文主要介紹了IDEA中Javaweb項目圖片加載不出來解決方案,感興趣的可以了解一下
    2023-10-10
  • 通過實例深入了解java序列化

    通過實例深入了解java序列化

    這篇文章主要介紹了通過實例深入了解java序列化,
    2019-06-06
  • MybatisPlus自動填充創(chuàng)建(更新)時間問題

    MybatisPlus自動填充創(chuàng)建(更新)時間問題

    在開發(fā)數(shù)據(jù)庫相關(guān)應(yīng)用時,手動設(shè)置創(chuàng)建和更新時間會導(dǎo)致代碼冗余,MybatisPlus提供了自動填充功能,通過實現(xiàn)MetaObjectHandler接口并重寫insertFill、updateFill方法,可以自動維護創(chuàng)建時間、更新時間等字段,極大簡化了代碼,這不僅提高了開發(fā)效率,也保證了數(shù)據(jù)的可追溯性
    2024-09-09

最新評論