一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - Java SpringBoot的相關知識點詳解

Java SpringBoot的相關知識點詳解

2022-02-12 15:38can_chen Java教程

這篇文章主要介紹了SpringBoot的相關知識點,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下

1. IOC和DI

首先,我們應該明確,IOC是一種思想,并不是Spring特有的,而是軟件工程逐步發展的一種產物,是一種優秀的編程思想,之所以我們經常會把IOC理解成是Spring特有的東西,是因為Spring框架可以幫助我們很好的去實現IOC。IOC代表的是控制反轉,控制的是什么?反轉的是什么?控制的是一個對象的創建、初始化和銷毀,沒有使用IOC之前,我們使用一個對象,會主動的去創建對象,也就是在需要使用這個對象的地方去執行A a = new A();類似這種語句,而使用了IOC之后,會把系統中所有需要使用到的對象交給IOC容器去托管,當我們的程序中需要使用到某個對象時,也不是我們直接去容器獲取這個對象,而是容器會主動的給我們這個對象,也就是說IOC容器會自動給程序中需要對象的地方給你注入對象,這就是反轉,把獲取對象的行為由主動變為被動,并且把控制權交給了容器。

DI代表的是依賴注入,什么是依賴注入?我們都知道,對象與對象之間一般都會有依賴關系的,例如對象A依賴于對象B,對象B又依賴于對象C,舉個例子,對象A中有個方法a,a方法的實現需要調用B對象的b方法,這就是依賴,引入IOC之前,我們會在A對象中new一個B對象,再通過B對象去調用b方法;引入IOC之后,我們都不會去主動創建對象了,都交給IOC容器去處理了,我們只需要在對象A中聲明一個B對象的成員變量,加上xml配置或者相關注解,IOC容器就可以我們自動實現注入。例如下面這段代碼,在MVC架構中,Controller層依賴Service層,我們只需要在Controller層聲明一個Service層的變量,并加上@Autowired注解,當IOC容器啟動時加載ApplicationController這個Bean到容器中時,會自動把ApplicationService這個Bean也注入進來。

Java SpringBoot的相關知識點詳解

依賴注入的實現方式有三種:構造函數注入、set方法注入以及接口注入;接口注入用的比較少,一般都是使用構造函數注入和set方法注入,另外還有一種字段注入,如上圖所示的注入方式就是字段注入,這種注入方式不是規范的,可以看到@Autowired注解會給出警告,不建議我們使用這種方式,但這種方式卻是使用最多的,因為它很方便。

Java SpringBoot的相關知識點詳解

以下是構造函數注入:

Java SpringBoot的相關知識點詳解

以下是set方法注入:

Java SpringBoot的相關知識點詳解

 

2. Spring容器加載Bean/創建對象的時機

默認情況下,程序啟動的時候,Spring就會把程序中需要用到的Bean加載到IOC容器中,也就是會一次性創建很多的對象到IOC容器中。當然,還有一種方式,就是當需要使用到某個Bean的時候,再去創建這個Bean到容器中,這就是延遲加載,或者叫延遲實例化。

如果我們希望某個Bean不要過早的被加載到容器中,使用到的時候再去創建,可以給這個Bean加上@Lazy注解。

Java SpringBoot的相關知識點詳解

關于@Lazy注解實現延遲加載,需要注意一個細節,我們給某個Bean加上@Lazy注解之后,并不一定就能實現延遲加載,有可能程序在啟動的時候,這個Bean還是會在一開始就被創建,會產生這種情況是因為這個Bean有可能在別處被引用到,也就是說別的Bean可能依賴了這個Bean,而依賴的這個Bean又沒有打上@Lazy注解,那么程序啟動的時候,創建這個依賴的Bean,也會把它所依賴的Bean一并注入,這就是導致@Lazy注解有時沒有生效的原因。

舉個例子,ApplicationController這個Bean依賴了ApplicationServiceImpl,我們只給ApplicationServiceImpl這個Bean加上@Lazy注解,是無法實現延遲加載的,需要ApplicationController這個Bean也加上@Lazy注解。

Java SpringBoot的相關知識點詳解

Java SpringBoot的相關知識點詳解

Java SpringBoot的相關知識點詳解

 

3. @Autowired注解

@Autowired注解的作用就是實現依賴注入,大部分情況下,我們使用@Autowired這個注解就可以滿足我們的需求了,但是我們需要知道這個注解的約定是什么,才能更好的使用它。首先,@Autowired注解實現的是按照類型注入,補充一個點:為了滿足ocp原則,使得代碼更加靈活便于擴展,我們倡導面向接口編程。例如下面這個例子,ApplicationService是一個接口,我們加上了@Autowired注解,按照類型注入的原則,IOC容器會去找ApplicationService接口的實現類去進行依賴注入,如果這個接口只有一個實現類,那么沒有問題,可以實現注入,如果這個接口有多個實現類,那么IOC容器會知道給我們注入哪一個實現類嗎,顯然是不知道的,但是@Autowired還有一種規則,就是根據類型匹配時,如果能匹配多個,會再根據Bean的名稱去匹配,如果Bean的名稱能匹配上,那么沒有問題,可以實現注入;如果Bean的名稱匹配不上,程序會報錯,因為IOC容器不知道給我們注入哪一個ApplicationService接口的實現類。

Java SpringBoot的相關知識點詳解

舉個例子,假設現在ApplicationService接口有兩個實現類ApplicationServiceImpl1(Bean名稱:applicationServiceImpl1)和ApplicationServiceImpl2(Bean名稱:applicationServiceImpl2),如果@Autowired注解作用的代碼是private ApplicationService applicationServiceImpl1;,那么注入的是ApplicationServiceImpl1這個Bean,如果@Autowired注解作用的代碼是private ApplicationService applicationServiceImpl2;,那么注入的是ApplicationServiceImpl2這個Bean,如果@Autowired注解作用的代碼是private ApplicationService applicationServiceImpl;,那么程序報錯,IOC容器知道為我們注入哪個Bean。

如果涉及一個接口有多個實現類的情況,我們建議使用@Autowired注解搭配@Qualifier注解,@Qualifier注解的實現機制是按照Bean的名稱進行注入。

例如下面這個例子,首先@Autowired注解會根據類型找到ApplicationService的實現類,@Qualifier注解再找到名稱為applicationServiceImpl的Bean進行注入。

Java SpringBoot的相關知識點詳解

PS:上面我們講的是@Autowired注解如果匹配到多個Bean不知道注入哪一個的時候會報錯,還有一種情況,如果@Autowired注解匹配不到任何對應的Bean也會報錯。

 

4. @Configuration配置類

一個類被加上了@Configuration注解,就表明這個類是一個配置類,@Configuration注解底層注解是@Component,也就是說,注解類也會被加載到IOC容器中,在注解類中,通常會聲明很多方法,這些方法的返回值是一個對象,并且方法加上了@Bean注解,這表明會將這些方法返回的對象加載到IOC容器中。例如:

Java SpringBoot的相關知識點詳解

@Configuration注解是用來替換Bean的xml配置,可以把@Configuration看作標簽,把@Bean注解看作標簽

傳統的xml配置是這樣的:

<beans>    <bean id = "people", class = "com.test.People">    </bean>    <bean id = "student", class = "com.test.Student">    </bean></beans>

思考一個問題:一般來說,把一個Bean加載到IOC容器中,不是通過@Component注解就可以實現嗎?況且@Configuration注解的底層注解還是@Component,那為什么還需要@Configuation+@Bean這套注解來加載某些Bean到IOC容器中呢?換言之,@Configuation+@Bean的真正作用是什么?

@Configuation+@Bean的作用就是可以將一些定制化的Bean(特殊的Bean)注入到IOC容器中,什么是定制化的Bean?舉個例子,有一個People類,有兩個屬性name和age,我們希望把People類加載到IOC容器中,并且使得IOC容器的這個Bean的name屬性值是小明,age屬性值是18。如果只是在People類上加@Component注解,是無法實現我們這個定制化的Bean的,因為IOC容器在啟動的時候,創建Bean,默認調用的都是某個類的無參構造函數(也存在調用帶參構造函數的情況,但是這種情況使用帶參構造函數,只是為了實現依賴注入,也就是構造函數注入,并非是給屬性賦值),也就是說無法給我們的屬性賦特殊的值,而使用@Configuation+@Bean就可以實現。例如:

Java SpringBoot的相關知識點詳解

Java SpringBoot的相關知識點詳解

通常來說,我們不會直接把屬性值寫死在代碼里,而是通過讀取配置文件的形式,雖然說@Configuration注解表明這個類已經是一個配置類了,可以充當配置文件來使用,但是對于一些變化的屬性,我們都會定義在普通配置文件里面,例如application.properties。

Java SpringBoot的相關知識點詳解

Java SpringBoot的相關知識點詳解

 

5. @Conditional條件注解

@Conditional注解的作用是滿足某個條件時,才會將這個Bean注入到IOC容器中。我們可以通過自定義一個Condition類的方式定制某個規則,當滿足這個規則才會注入Bean,例如:

Java SpringBoot的相關知識點詳解

Java SpringBoot的相關知識點詳解

通常,我們直接使用一些成品條件注解就可以滿足我們的需求了。常用成品條件注解如下:

Java SpringBoot的相關知識點詳解

 

6. SpringBoot的自動配置/自動裝配

自動裝配是SpringBoot最核心的東西,學習自動裝配,我們首先應該了解自動裝配是什么,做了哪些事情?其次需要明確自動裝配存在的意義,也就是說自動裝配的好處是什么?最后再去了解自動裝配的原理。按照這個流程下來,才能更好的掌握自動裝配這個知識點。

a.自動裝配做了什么事情?就是SpringBoot會自動把一些第三方的庫或者SDK需要使用到的很多Bean都自動幫我們加載到IOC容器中。

b.自動裝配的好處是什么?基于IOC思想,任何程序中使用到的Bean都需要注入IOC容器中進行托管,也就是說,我們引用一些第三方的庫/依賴,例如Mongodb、Redis、Hadoop,也是需要把這些第三方的庫涉及的Bean都加載到IOC容器中的。如果沒有自動裝配,那么如何把第三方的庫里面的很多Bean都加載到我們的IOC容器中來,給每一個相關的類打上@Component注解?不是這樣的,我們所引用的第三方庫一般都是以jar包的形式存在,并不是直接給源碼。即便是可以通過打上@Component注解的方式,試想我們的工作量會增加多少,引用一個第三方庫可能涉及很多的Bean,并且有些Bean又可能是比較復雜的,我們不可能手動的將他們一個個注入容器,而SpringBoot都幫我們做好了,這就是自動裝配的好處。

c.自動裝配的原理

首先,在SpringBoot程序的主啟動類上,有一個非常重要的注解:@SpringBootApplication,進入到這個注解,可以發現底層由三個注解組成(元注解除外)

Java SpringBoot的相關知識點詳解

@SpringBootConfiguration:表明SpringBoot程序的主啟動類也是一個配置類

@ComponentScan:指定包掃描路徑,程序啟動時,會根據指定的包掃描路徑去加載Bean

@EnableAutoConfiguration:最重要的一個注解,我們可以理解成這個注解的作用是開啟自動裝配

進入到@EnableAutoConfiguration,可以發現底層由兩個注解組成(元注解除外)

Java SpringBoot的相關知識點詳解

我們主要研究@Import注解,這個注解有兩種實現方式,第一種是指定一個或多個配置類,例如:@Import(TetsConfiguration.class)那么IOC容器就會將這個配置類加載到容器中來,另一種實現方式是指定一個ImportSelector類的子類,例如@Import(AutoConfigurationImportSelector.class)這個ImportSelector類的子類會去實現selectImports方法,該方法的返回值是一個字符串數組,代表要加載的配置類名稱列表。

SpringBoot自動裝配默認使用第二種方式,我們進到AutoConfigurationImportSelector這個類里面,發現它確實實現了selectImports方法。通過這個方法,SpringBoot就可以知道我們需要自動裝配哪些配置類

Java SpringBoot的相關知識點詳解

我們再進入getAutoConfigurationEntry方法,這個方法里面有一個核心方法getCandidateConfigurations,翻譯過來就是獲取候選的配置類

Java SpringBoot的相關知識點詳解

getCandidateConfigurations方法實現邏輯就是:會去讀取某一個配置文件,根據這個配置文件的值返回自動裝配要裝配的配置類名稱列表

Java SpringBoot的相關知識點詳解

我們進入到SpringFactoriesLoader類,可以知道getCandidateConfigurations讀取的配置文件就是META-INF下面的spring.factories

Java SpringBoot的相關知識點詳解

spring.factories的位置

Java SpringBoot的相關知識點詳解

spring.factories配置文件主要就聲明了很多自動配置類的名稱,截取部分如下:

Java SpringBoot的相關知識點詳解

總結一下,我們一路追蹤源碼下來,無非確定了一件事,SpringBoot自動裝配時裝配了哪些配置類,這些配置類的定義都存在于spring.factories配置文件中。

另外,我們需要明確,SpringBoot自動裝配時也不是把所有自動配置類定義的Bean都加載到IOC容器中,因為這些Bean大部分都會加上條件注解,需要滿足一定的條件才會被加載,例如,我們進入某一個自動配置類看一下

Java SpringBoot的相關知識點詳解

 

總結

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關注服務器之家的更多內容!

原文鏈接:https://blog.csdn.net/can_chen/article/details/120614018

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 亚洲国产成人精品 | 超碰97| 把女的下面扒开添视频 | 思思99热久久精品在2019线 | 9420高清完整版在线观看国语 | 欧美成人福利 | 国内9lporm自拍视频区 | 97色综合 | 色一情一区二区三区四区 | 欧洲久久 | 91精品国产91热久久p | 国产成人影院在线观看 | 青青青青青操 | 欧美性色黄大片四虎影视 | 国内9lporm自拍视频区 | 三级黄片毛片 | narutomanga玖辛奈本子 | 国产精品久热 | 特黄aa级毛片免费视频播放 | 国色天香社区视频免费观看3 | 色综合网天天综合色中文男男 | 国产麻豆精品免费视频 | 五月丁香啪啪. | 顶级尤物极品女神福利视频 | 91会员 | 五月丁开婷婷 | 高清国产激情视频在线观看 | 亚洲精品国产精品国自产观看 | 99久久国产综合精品麻豆 | 国产婷婷成人久久av免费高清 | 国产欧美va欧美va香蕉在线观看 | 亚洲第一人黄所 | 精品综合久久久久久88小说 | 精品视频中文字幕 | 91桃色污 | 色老板免费 | bl文全肉高h湿被灌尿 | 亚洲羞羞裸色私人影院 | 亚洲成年www | 国产精品九九免费视频 | 亚洲乱人伦在线 |