最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java SpringBoot的相關(guān)知識點詳解

 更新時間:2021年10月09日 08:42:06   作者:can_chen  
這篇文章主要介紹了SpringBoot的相關(guān)知識點,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下

1. IOC和DI

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

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

請?zhí)砑訄D片描述

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

請?zhí)砑訄D片描述

以下是構(gòu)造函數(shù)注入:

請?zhí)砑訄D片描述

以下是set方法注入:

請?zhí)砑訄D片描述

2. Spring容器加載Bean/創(chuàng)建對象的時機(jī)

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

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

請?zhí)砑訄D片描述

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

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

請?zhí)砑訄D片描述

請?zhí)砑訄D片描述

請?zhí)砑訄D片描述

3. @Autowired注解

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

請?zhí)砑訄D片描述

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

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

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

請?zhí)砑訄D片描述

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

4. @Configuration配置類

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

請?zhí)砑訄D片描述

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

傳統(tǒng)的xml配置是這樣的:

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

思考一個問題:一般來說,把一個Bean加載到IOC容器中,不是通過@Component注解就可以實現(xiàn)嗎?況且@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注解,是無法實現(xiàn)我們這個定制化的Bean的,因為IOC容器在啟動的時候,創(chuàng)建Bean,默認(rèn)調(diào)用的都是某個類的無參構(gòu)造函數(shù)(也存在調(diào)用帶參構(gòu)造函數(shù)的情況,但是這種情況使用帶參構(gòu)造函數(shù),只是為了實現(xiàn)依賴注入,也就是構(gòu)造函數(shù)注入,并非是給屬性賦值),也就是說無法給我們的屬性賦特殊的值,而使用@Configuation+@Bean就可以實現(xiàn)。例如:

請?zhí)砑訄D片描述

請?zhí)砑訄D片描述

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

請?zhí)砑訄D片描述

請?zhí)砑訄D片描述

5. @Conditional條件注解

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

請?zhí)砑訄D片描述

請?zhí)砑訄D片描述

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

請?zhí)砑訄D片描述

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

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

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

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

c. 自動裝配的原理

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

請?zhí)砑訄D片描述

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

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

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

進(jìn)入到@EnableAutoConfiguration,可以發(fā)現(xiàn)底層由兩個注解組成(元注解除外)

請?zhí)砑訄D片描述

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

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

請?zhí)砑訄D片描述

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

請?zhí)砑訄D片描述

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

請?zhí)砑訄D片描述

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

請?zhí)砑訄D片描述

spring.factories的位置

請?zhí)砑訄D片描述

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

請?zhí)砑訄D片描述

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

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

請?zhí)砑訄D片描述

總結(jié)

本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

  • Feign如何實現(xiàn)第三方的HTTP請求

    Feign如何實現(xiàn)第三方的HTTP請求

    這篇文章主要介紹了Feign如何實現(xiàn)第三方的HTTP請求,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-10-10
  • java  LinkedList類詳解及實例代碼

    java LinkedList類詳解及實例代碼

    這篇文章主要介紹了java LinkedList類詳解及實例代碼的相關(guān)資料,需要的朋友可以參考下
    2017-01-01
  • Java權(quán)重隨機(jī)的實現(xiàn)方法

    Java權(quán)重隨機(jī)的實現(xiàn)方法

    這篇文章主要介紹了Java權(quán)重隨機(jī)的實現(xiàn)方法,實例分析了權(quán)重隨機(jī)算法的原理與完整實現(xiàn)方法,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-01-01
  • java實現(xiàn)Composite組合模式的實例代碼

    java實現(xiàn)Composite組合模式的實例代碼

    這篇文章主要介紹了java實現(xiàn)Composite組合模式,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-01-01
  • Java中的NoSuchMethodException異常原因以及解決方案詳解

    Java中的NoSuchMethodException異常原因以及解決方案詳解

    這篇文章主要介紹了Java中的NoSuchMethodException異常原因以及解決方案詳解,NoSuchMethodException是Java反射機(jī)制中的異常,在嘗試通過反射獲取方法時,找不到指定的方法,通常發(fā)生在調(diào)用?Class?對象的方法時,當(dāng)方法名或方法參數(shù)不匹配時拋出該異常,需要的朋友可以參考下
    2024-02-02
  • 基于SpringBoot實現(xiàn)IP黑白名單的詳細(xì)步驟

    基于SpringBoot實現(xiàn)IP黑白名單的詳細(xì)步驟

    IP黑白名單是網(wǎng)絡(luò)安全管理中常見的策略工具,用于控制網(wǎng)絡(luò)訪問權(quán)限,根據(jù)業(yè)務(wù)場景的不同,其應(yīng)用范圍廣泛,比如比較容易被盜刷的短信接口、文件接口,都需要添加IP黑白名單加以限制,所以本文給大家介紹了基于SpringBoot實現(xiàn)IP黑白名單的詳細(xì)步驟,需要的朋友可以參考下
    2024-01-01
  • java9區(qū)分opens與exports

    java9區(qū)分opens與exports

    本篇文章主要給大家講述了java9中opens與exports的區(qū)別以及用法的不同之處,一起學(xué)習(xí)下吧。
    2018-02-02
  • 編程入門:掌握J(rèn)ava運算符技巧

    編程入門:掌握J(rèn)ava運算符技巧

    掌握J(rèn)ava運算符技巧,能讓你的編程之旅輕松許多,本指南將帶你深入了解如何巧妙地使用這些強(qiáng)大的工具,讓代碼不僅高效,還充滿樂趣,跟著我們一起,讓你的Java代碼在運算符的魔法下煥發(fā)新生!
    2023-12-12
  • Java GUI插入圖片不顯示問題解決方法

    Java GUI插入圖片不顯示問題解決方法

    大家好,本篇文章主要講的是Java GUI插入圖片不顯示問題解決方法,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下,方便下次瀏覽
    2022-01-01
  • 基于python locust庫實現(xiàn)性能測試

    基于python locust庫實現(xiàn)性能測試

    這篇文章主要介紹了基于python locust庫實現(xiàn)性能測試,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-05-05

最新評論

咸阳市| 丰城市| 泸定县| 通山县| 勃利县| 肇庆市| 离岛区| 嫩江县| 黄山市| 宁波市| 临安市| 河津市| 青龙| 特克斯县| 长顺县| 麟游县| 盐边县| 梁山县| 淄博市| 哈尔滨市| 平果县| 建瓯市| 南宫市| 河源市| 新野县| 扎兰屯市| 斗六市| 泰州市| 龙里县| 阜南县| 新晃| 阜南县| 临颍县| 张北县| 德阳市| 富蕴县| 永兴县| 布拖县| 同仁县| 通许县| 津南区|