吴忠躺衫网络科技有限公司

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內(nèi)不再提示

什么是 SpringBoot?

jf_78858299 ? 來源:CSDN ? 作者:CSDN雙子孤狼 ? 2023-04-07 11:28 ? 次閱讀

前言如果我們想要使用傳統(tǒng)意義上的 Spring 應用,那么需要配置大量的 xml 文件才可以啟動,而且隨著項目的越來越龐大,配置文件也會越來越繁瑣,這在一定程度上也給開發(fā)者帶來了困擾,于是 SpringBoot 就應運而生了。

什么是 SpringBoot

2012 年 10 月,一個叫 Mike Youngstrom 的人在 Spring Jira 中創(chuàng)建了一個功能請求,要求在 Spring Framework 中支持無容器 Web 應用程序體系結(jié)構(gòu),提出了在主容器引導 Spring 容器內(nèi)配置 Web 容器服務。這件事情對 SpringBoot 的誕生應該說是起到了一定的推動作用。

SpringBoot 的誕生就是為了簡化 Spring 中繁瑣的 XML 配置,其本質(zhì)依然是 Spring 框架,使用 SpringBoot 之后可以不使用任何 XML 配置來啟動一個服務,使得我們在使用微服務架構(gòu)時可以更加快速的建立一個應用。

SpringBoot 具有以下特點:

  • 創(chuàng)建獨立的 Spring 應用。
  • 直接嵌入了 Tomcat、Jetty 或 Undertow(不需要部署 WAR 文件)。
  • 提供了固定的配置來簡化配置。
  • 盡可能地自動配置 Spring 和第三方庫。
  • 提供可用于生產(chǎn)的特性,如度量、運行狀況檢查和外部化配置。
  • 完全不需要生成代碼,也不需要 XML 配置。

SpringBoot 這些特點中最重要的兩條就是約定優(yōu)于配置和自動裝配。

約定優(yōu)于配置

SpringBoot的約定由于配置主要體現(xiàn)在以下方面:

maven 項目的配置文件存放在 resources 資源目錄下。maven 項目默認編譯后的文件放于 target 目錄。maven 項目默認打包成 jar 格式。配置文件默認為 application.yml 或者 application.yaml 或者 application.properties。默認通過配置文件 spring.profiles.active 來激活配置。

自動裝配

自動裝配則是 SpringBoot 的核心,自動裝配是如何實現(xiàn)的呢?為什么我們只要引入一個 starter 組件依賴就能實現(xiàn)自動裝配呢,接下來就讓我們一起來探討下 SpringBoot 的自動裝配機制。

相比較于傳統(tǒng)的 Spring 應用,搭建一個 SpringBoot 應用,我們只需要引入一個注解 @SpringBootApplication,就可以成功運行。

我們就從 SpringBoot 的這個注解開始入手,看看這個注解到底替我們做了什么。圖片

前面四個不用說,是定義一個注解所必須的,關(guān)鍵就在于后面三個注解:@SpringBootConfiguration@EnableAutoConfiguration@ComponentScan。也就是說我們?nèi)绻挥?@SpringBootApplication 這個復合注解,而是直接使用最下面這三個注解,也能啟動一個 SpringBoot 應用。

@SpringBootConfiguration 注解

[這個注解我們點進去就可以發(fā)現(xiàn),它實際上就是一個 @Configuration 注解,這個注解大家應該很熟悉了,加上這個注解就是為了讓當前類作為一個配置類交由SpringIOC 容器進行管理,因為前面我們說了,SpringBoot 本質(zhì)上還是 Spring,所以原屬于 Spring 的注解 @ConfigurationSpringBoot 中也可以直接應用。

@ComponentScan 注解

[這個注解也很熟悉,用于定義 Spring 的掃描路徑,等價于在 xml 文件中配置 context:component-scan,假如不配置掃描路徑,那么 Spring 就會默認掃描當前類所在的包及其子包中的所有標注了 @Component@Service@Controller 等注解的類。

@EnableAutoConfiguration

這個注解才是實現(xiàn)自動裝配的關(guān)鍵,點進去之后發(fā)現(xiàn),它是一個由@AutoConfigurationPackage@Import 注解組成的復合注解。圖片

@EnableXXX 注解也并不是 SpringBoot 中的新注解,這種注解在 Spring 3.1 版本就開始出現(xiàn)了,比如開啟定時任務的注解 @EnableScheduling 等。

@Import 注解

[這個注解比較關(guān)鍵,我們通過一個例子來說明一下。

定義一個普通類TestImport,不加任何注解,我們知道這個時候這個類并不會被 Spring 掃描到,也就是無法直接注入這個類:

public class TestImport {
}

現(xiàn)實開發(fā)中,假如就有這種情況,定義好了一個類,即使加上了注解,也不能保證這個類一定被 Spring 掃描到,這個時候該怎么做呢?

這時候我們可以再定義一個類 MyConfiguration,保證這個類可以被 Spring 掃描到,然后通過加上 @Import 注解來導入 TestImport 類,這時候就可以直接注入 TestImport 了:

@Configuration
@Import(TestImport.class)
public class MyConfiguration {
}

所以這里的 @Import 注解其實就是為了去導入一個類 AutoConfigurationImportSelector,接下來我們需要分析一下這個類。

AutoConfigurationImportSelector 類

進入這個類之后,有一個方法,這個方法很好理解,首先就是看一下 AnnotationMetadata(注解的元信息),有沒有數(shù)據(jù),沒有就說明沒導入直接返回一個空數(shù)組,否則就調(diào)用 getAutoConfigurationEntry 方法:圖片

進入 getAutoConfigurationEntry 方法:

圖片

這個方法里面就是通過調(diào)用 getCandidateConfigurations 來獲取候選的 Bean,并將其存為一個集合,最后經(jīng)過去重,校驗等一系列操作之后,被封裝成 AutoConfigurationEntry 對象返回。

繼續(xù)進入 getCandidateConfigurations 方法,這時候就幾乎看到曙光了:圖片

這里面再繼續(xù)點擊去就沒必要了,看錯誤提示大概就知道了,loadFactoryNames 方法會去 META-INF/spring.factories 文件中根據(jù) EnableAutoConfiguration 的全限定類名獲取到我們需要導入的類,而 EnableAutoConfiguration 類的全限定類名為 org.springframework.boot.autoconfigure.EnableAutoConfiguration,那么就讓我們打開這個文件看一下:圖片

可以看到,這個文件中配置了大量的需要自動裝配的類,當我們啟動 SpringBoot 項目的時候,SpringBoot會掃描所有jar 包下面的 META-INF/spring.factories 文件,并根據(jù) key 值進行讀取,最后在經(jīng)過去重等一些列操作得到了需要自動裝配的類。

需要注意的是:上圖中的 spring.factories 文件是在 spring-boot-autoconfigure 包下面,這個包記錄了官方提供的 stater 中幾乎所有需要的自動裝配類,所以并不是每一個官方的 starter 下都會有 spring.factories 文件。

談談 SPI 機制

通過 SpringFactoriesLoader來讀取配置文件 spring.factories 中的配置文件的這種方式是一種 SPI 的思想。那么什么是 SPI 呢?

SPI,Service Provider Interface。即:接口服務的提供者。就是說我們應該面向接口(抽象)編程,而不是面向具體的實現(xiàn)來編程,這樣一旦我們需要切換到當前接口的其他實現(xiàn)就無需修改代碼。

Java 中,數(shù)據(jù)庫驅(qū)動就使用到了 SPI 技術(shù),每次我們只需要引入數(shù)據(jù)庫驅(qū)動就能被加載的原因就是因為使用了 SPI 技術(shù)。

打開 DriverManager 類,其初始化驅(qū)動的代碼如下:

圖片

進入 ServiceLoader 方法,發(fā)現(xiàn)其內(nèi)部定義了一個變量:

private static final String PREFIX = "META-INF/services/";

這個變量在下面加載驅(qū)動的時候有用到,下圖中的 servicejava.sql.Driver

圖片

所以就是說,在數(shù)據(jù)庫驅(qū)動的 jar 包下面的 META-INF/services/ 下有一個文件 java.sql.Driver,里面記錄了當前需要加載的驅(qū)動,我們打開這個文件可以看到里面記錄的就是驅(qū)動的全限定類名:

圖片

@AutoConfigurationPackage 注解

從這個注解繼續(xù)點進去之后可以發(fā)現(xiàn),它最終還是一個 @Import 注解:

圖片

這個時候它導入了一個 AutoConfigurationPackages 的內(nèi)部類 Registrar, 而這個類其實作用就是讀取到我們在最外層的 @SpringBootApplication 注解中配置的掃描路徑(沒有配置則默認當前包下),然后把掃描路徑下面的類都加到數(shù)組中返回。

圖片

手寫一個 stater 組件

了解完自動裝配的原理,接下來就可以動手寫一個自己的 starter 組件了。

starter 組件命名規(guī)則

SpringBoot 官方的建議是,如果是我們開發(fā)者自己開發(fā)的 starter 組件(即屬于第三方組件),那么命名規(guī)范是{name}-spring-boot-starter,而如果是 SpringBoot 官方自己開發(fā)的組件,則命名為 spring-boot-starter-{name}

當然,這只是一個建議,如果非不按這個規(guī)則也沒什么問題,但是為了更好的識別區(qū)分,還是建議按照這個規(guī)則來命名。

手寫 starter

寫一個非常簡單的組件,這個組件只做一件事,那就是實現(xiàn) fastjson 序列化。

  • 新建一個 SpringBoot 應用 lonelyWolf-spring-boot-starter
  • 修改 pom 文件,并新增 fastjson 依賴(省略了部分屬性)。
<parent>
    <groupId>org.springframework.boot<span class="hljs-name"groupId>
    <artifactId>spring-boot-starter-parent<span class="hljs-name"artifactId>
    <version>2.4.0<span class="hljs-name"version>
    <relativePath/>
<span class="hljs-name"parent>

<groupId>com.lonely.wolf.note<span class="hljs-name"groupId>
<artifactId>lonelyWolf-spring-boot-starter<span class="hljs-name"artifactId>
<version>1.0.0-SNAPSHOT<span class="hljs-name"version>

<dependencies>
    <dependency>
      <groupId>org.springframework.boot<span class="hljs-name"groupId>
      <artifactId>spring-boot-starter<span class="hljs-name"artifactId>
    <span class="hljs-name"dependency>

    <dependency>
      <groupId>com.alibaba<span class="hljs-name"groupId>
      <artifactId>fastjson<span class="hljs-name"artifactId>
      <version>1.2.72<span class="hljs-name"version>
    <span class="hljs-name"dependency>
<span class="hljs-name"dependencies>
  • 新建一個序列化類 JsonSerial 類來實現(xiàn) fastjson 序列化。
public class JsonSerial {
    public
  • 新建一個自動裝配類 MyAutoConfiguration 來生成 JsonSerial
@Configuration
public class MyAutoConfiguration {

    @Bean
    public JsonSerial jsonSerial(){
        return new JsonSerial();
    }
}
  • 完成之后將其打成一個 jar 包,然后再另一個 SpringBoot 中引入依賴:
<dependency>
     <groupId>com.lonely.wolf.note<span class="hljs-name"groupId>
     <artifactId>lonelyWolf-spring-boot-starter<span class="hljs-name"artifactId>
     <version>1.0.0-SNAPSHOT<span class="hljs-name"version>
<span class="hljs-name"dependency>
  • 這時候在這個 SpringBoot 應用中直接注入 JsonSerial 對象會直接提示找不到這個對象:

圖片

這是因為 MyAutoConfiguration 這個類是在外部 jar 包之中,并沒有被掃描到(需要注意的是,假如剛好 jar 包的路徑和掃描的路徑相同,那么是可以被掃描到的,但是在實際項目中,我們不可能確保引入的 jar 包能被掃描到,所以才需要通過配置的方式來導入),所以我們還需要導入這個外部配置類。

  • resources 目錄下新建一個文件 META-INF/spring.factories 文件,文件內(nèi)新增一個如下配置:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\\
com.lonely.wolf.note.MyAutoConfiguration

這樣,SpringBoot 就會將 MyAutoConfiguration 進行管理,從而得到 JsonSerial 對象,這樣就可以直接注入使用了。

總結(jié)

本文從為什么要有 SpringBoot,以及 SpringBoot 到底方便在哪里開始入手,逐步分析了 SpringBoot 自動裝配的原理,最后手寫了一個簡單的 start 組件,通過實戰(zhàn)來體會了 SpringBoot 自動裝配機制的奧妙。

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • JAVA
    +關(guān)注

    關(guān)注

    19

    文章

    2974

    瀏覽量

    105138
  • spring
    +關(guān)注

    關(guān)注

    0

    文章

    340

    瀏覽量

    14388
  • 自動裝配
    +關(guān)注

    關(guān)注

    0

    文章

    7

    瀏覽量

    670
  • SpringBoot
    +關(guān)注

    關(guān)注

    0

    文章

    174

    瀏覽量

    201
收藏 人收藏

    評論

    相關(guān)推薦

    SpringBoot配置Mybatis的2個錯誤和修正

    SpringBoot】配置Mybatis錯誤
    發(fā)表于 04-19 10:31

    SpringBoot中的Druid介紹

    SpringBoot中Druid數(shù)據(jù)源配置
    發(fā)表于 05-07 09:21

    基于SpringBoot mybatis方式的增刪改查實現(xiàn)

    SpringBoot mybatis方式實現(xiàn)增刪改查
    發(fā)表于 06-18 16:56

    SpringBoot知識總結(jié)

    SpringBoot干貨學習總結(jié)
    發(fā)表于 08-01 10:40

    springboot spring data jpa使用總結(jié)

    【本人禿頂程序員】springboot專輯:spring data jpa的使用
    發(fā)表于 04-15 11:38

    怎么學習SpringBoot

    SpringBoot學習之路(X5)- 整合JPA
    發(fā)表于 06-10 14:52

    SpringBoot 學習筆記

    SpringBoot 學習筆記 【整合JWT】添加依賴創(chuàng)建工具類登錄獲取jwt使用jwtDemo源碼參考資料添加依賴pom.xml...com.auth0java-jwt3.12.0
    發(fā)表于 07-01 07:27

    springboot集成mqtt

    springboot集成mqtt,大綱一.數(shù)據(jù)入庫1.數(shù)據(jù)入庫解決方案二.開發(fā)實時訂閱發(fā)布展示頁面1.及時通訊技術(shù)2.技術(shù)整合
    發(fā)表于 07-16 07:53

    怎樣去使用springboot

    怎樣去使用springboot呢?學習springboot需要懂得哪些?
    發(fā)表于 10-25 07:13

    SpringBoot嵌入式Servlet容器啟動原理是什么

    SpringBoot嵌入式Servlet容器啟動原理思維導圖
    發(fā)表于 12-20 07:26

    SpringBoot應用啟動運行run方法

    什么時候創(chuàng)建嵌入式的Servlet容器工廠?什么時候獲取嵌入式的Servlet容器并啟動Tomcat;獲取嵌入式的Servlet容器工廠:1)、SpringBoot應用啟動運行run方法2
    發(fā)表于 12-20 06:16

    SpringBoot配置嵌入式Servlet

    SpringBoot配置嵌入式Servlet容器定制和修改Servlet容器相關(guān)配置全局配置文件編寫WebServerFactoryCustomizer注冊Servlet三大組件注冊Servlet
    發(fā)表于 12-20 06:19

    SpringBoot實現(xiàn)多線程

    SpringBoot實現(xiàn)多線程
    的頭像 發(fā)表于 01-12 16:59 ?1883次閱讀
    <b class='flag-5'>SpringBoot</b>實現(xiàn)多線程

    SpringBoot的核心注解1

    今天跟大家來探討下SpringBoot的核心注解@SpringBootApplication以及run方法,理解下springBoot為什么不需要XML,達到零配置
    的頭像 發(fā)表于 04-07 14:34 ?739次閱讀
    <b class='flag-5'>SpringBoot</b>的核心注解1

    SpringBoot的核心注解2

    今天跟大家來探討下SpringBoot的核心注解@SpringBootApplication以及run方法,理解下springBoot為什么不需要XML,達到零配置
    的頭像 發(fā)表于 04-07 14:34 ?1994次閱讀
    <b class='flag-5'>SpringBoot</b>的核心注解2
    百家乐官网游戏打水方法| 百家乐赌博论坛| 娱乐城开户送现金| 大世界百家乐官网娱乐场| 圣淘沙百家乐的玩法技巧和规则 | 百家乐官网永利娱乐场| 战神百家乐的玩法技巧和规则| 邯郸县| 百家乐计算法| 百家乐官网庄河闲的赌法| 百家乐无损打法| 澳门百家乐官网如何算牌| 百家乐娱乐网网77scs| 保时捷百家乐官网娱乐城| 百家乐是个什么样的游戏| 百家乐官网娱乐城怎么样| 百家乐透明发牌靴| 百家乐官网路单之我见| 百家乐技术辅助软件| 百家乐官网黑牌靴| 澳门百家乐怎么玩| 百家乐官网诀| 新皇冠现金网怎么样| 至尊百家乐官网于波| 日博| 百家乐赢钱公式1| 百家乐官网经验在哪找| 百家乐知道| 百家乐官网的分析| 澳盈88娱乐城| 钱百家乐取胜三步曲| 百家乐官网纯数字玩法| 威尼斯人娱乐开户| 24山方位| 平博百家乐官网游戏| 澳门百家乐赌场文| 网上百家乐官网娱乐网| 娱网棋牌大厅下载| 澳门百家乐文章| 百家乐官网菲律宾| 沾益县|