久久r热视频,国产午夜精品一区二区三区视频,亚洲精品自拍偷拍,欧美日韩精品二区

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

java進(jìn)階之了解SpringBoot的配置原理

瀏覽:102日期:2022-08-11 11:00:44
目錄一、Spring Boot的特點(diǎn)二、了解容器的功能三、原配置文件的引入四、自動(dòng)配置原理五、修改默認(rèn)配置(約定大于配置)六、總結(jié)一、Spring Boot的特點(diǎn)

首先我們要知道 Spring Boot 在底層已經(jīng)為我們添加好了很多依賴。比如我們常用的Tomcat,Spring,SpringMVC這些,甚至連mysql數(shù)據(jù)庫(kù)的依賴也為我們添加好了

java進(jìn)階之了解SpringBoot的配置原理

不過(guò) SpringBoot 2.5.0 使用的mysql依賴版本是8.0.25的,如果還在使用 mysql 5 版本的小伙伴們就需要在項(xiàng)目的 pom.xml 文件中再次指定自己所用的依賴版本號(hào)。(因?yàn)?maven 在引入依賴時(shí)采取就近原則,你如果指定了依賴版本號(hào)的話,它會(huì)加載離它近的,而不會(huì)去加載遠(yuǎn)的)

java進(jìn)階之了解SpringBoot的配置原理

例如,我要修改 mysql 依賴的版本為5.1.43

//在當(dāng)前項(xiàng)目里面重寫配置 <properties><mysql.version>5.1.43</mysql.version> </properties>二、了解容器的功能

添加組件

@Configuration、@Bean注解

首先,這個(gè)注解是寫在類上面的,告訴 spring boot 這是一個(gè)配置類,等同于 以前的配置文件

配置類里面使用@Bean標(biāo)注在方法上給容器注冊(cè)組件,默認(rèn)情況下是單例的。以方法名就是組件的 id 。返回類型就是組件類型。返回的值,就是組件在容器中的實(shí)例

為什么他會(huì)是單例的呢? 原因是在@Configuration注解的源碼中,還定義了一個(gè)屬性 proxyBeanMethods ,默認(rèn)值是 true。

java進(jìn)階之了解SpringBoot的配置原理

當(dāng)然我們也可以修改他的值為false,這樣他就會(huì)創(chuàng)建多個(gè)對(duì)象了。

舉個(gè)例子:

java進(jìn)階之了解SpringBoot的配置原理

我現(xiàn)在在配置類里面定義了一個(gè)組件,他會(huì)返回一個(gè) User 對(duì)象,當(dāng)proxyBeanMethods = true 時(shí),無(wú)論調(diào)用多少次 user01() 方法,在容器中都只會(huì)存在一個(gè)實(shí)例對(duì)象,但我現(xiàn)在把它改為 false ,來(lái)測(cè)試一下他到底是不是能創(chuàng)建多個(gè)實(shí)例了。

在主方法中進(jìn)行測(cè)試:

User user=config.user01(); User user1=config.user01(); System.out.println(user==user1);

最后輸出的結(jié)果是

false

這就說(shuō)明現(xiàn)在創(chuàng)建了兩個(gè)對(duì)象了,在容器中user和user1并不是指向同一塊內(nèi)存地址

那我們什么時(shí)候可以把它改成 false 來(lái)使用呢? 這就要設(shè)計(jì)到兩種編寫Spring Boot的方式了

一種是FULL模式 全模式(單例) 另一種是Lite模式 輕量級(jí)模式(非單例)

如果有組件依賴必須使用Full模式(默認(rèn))。其他默認(rèn)是否Lite模式

Import注解

加入 IOC 容器的方式有很多種,上面的@Bean是一種,這里提到的@Import也是用來(lái)注冊(cè)組件的,@Import注解可以用于導(dǎo)入第三方包 (當(dāng)然@Bean也可以)

它是寫在類上面的,

java進(jìn)階之了解SpringBoot的配置原理

它所創(chuàng)建的組件 id 默認(rèn)是類的全限定名稱

java進(jìn)階之了解SpringBoot的配置原理

具體用法參考:b站Spring注解驅(qū)動(dòng)教程

Conditional注解

條件裝配:滿足Conditional指定的條件,則進(jìn)行組件注入

@Conditional注解下面還有許多的子注解

java進(jìn)階之了解SpringBoot的配置原理

因?yàn)樗淖幼⒔鈱?shí)在太多了,下面我們具體實(shí)現(xiàn)一個(gè)例子來(lái)說(shuō)明一下它的功能

先在 User 類中再加入一個(gè) Pet 屬性

java進(jìn)階之了解SpringBoot的配置原理

現(xiàn)在我希望容器在沒(méi)有 Pet 的情況下,我也不要 User 對(duì)象

要實(shí)現(xiàn)這個(gè)需求,可以這樣做,在 User 組件前面添加@ConditionalOnBean注解,并指定條件為 Pet 組件的 id 來(lái)進(jìn)行限制

java進(jìn)階之了解SpringBoot的配置原理

執(zhí)行測(cè)試方法

java進(jìn)階之了解SpringBoot的配置原理

運(yùn)行結(jié)果:

容器中是否有tomcat:false容器中是否有user:false

這樣就對(duì)組件 User 的注冊(cè)加以限制了

也可以把@ConditionalOnBean(name='tom')注解加在配置類上面,當(dāng)容器中有 tom 組件時(shí),這個(gè)類中的其他組件才會(huì)生效,否則不生效

三、原配置文件的引入

如果你原有的項(xiàng)目還是使用 beans.xml 等配置文件的方式來(lái)注冊(cè)組件的話,SpringBoot 是肯定無(wú)法自動(dòng)配置的,那怎么樣才能讓SpringBoot用我這個(gè)配置文件去注冊(cè)組件呢?

@ImportResource注解

使用@ImportResource注解可以引入以前那種 xml 配置文件的方式寫的組件

使用方法:直接加在現(xiàn)在的配置類上面,例如:

@ImportResource('classpath:beans.xml')

配置綁定

配置綁定是什么意思呢?其實(shí)就是使用Java讀取到properties文件中的內(nèi)容,并且把它封裝到JavaBean中,以供隨時(shí)使用

具體做法:使用@ConfigurationProperties注解

這個(gè)注解是加在你需要從 properties 屬性配置文件中要導(dǎo)入的屬性的類上面。

比如:我現(xiàn)在寫了一個(gè) Car 類,然后在 properties 文件中寫好了它的屬性

java進(jìn)階之了解SpringBoot的配置原理java進(jìn)階之了解SpringBoot的配置原理

( 注意:properties 文件中的所有屬性均要小寫,駝峰命名法也不行,可以用 - 或 _ 來(lái)代替 )

我們想要將配置文件中定義好的屬性綁定到實(shí)例對(duì)象上的話,就可以在 Car 這個(gè)類上面加上@ConfigurationProperties(prefix = 'mycar'),prefix 代表前綴的意思。

java進(jìn)階之了解SpringBoot的配置原理

單加上這一個(gè)注解還不行,因?yàn)榇藭r(shí)容器中還沒(méi)有這個(gè)對(duì)象,可以采用兩種方式來(lái)把 Car 這個(gè)對(duì)象加入容器中:

1.使用@Component注解

2.使用@EnableConfigurationProperties注解

@Component+@ConfigurationProperties

在@ConfigurationProperties注解上方加上@Component注解,即可將 Car 加入到容器中

測(cè)試方法:

java進(jìn)階之了解SpringBoot的配置原理

運(yùn)行,訪問(wèn) “/car” 查看結(jié)果

java進(jìn)階之了解SpringBoot的配置原理

@EnableConfigurationProperties+@ConfigurationProperties

使用@EnableConfigurationProperties注解則需要在配置類上面添加,而不是 Car 上面

java進(jìn)階之了解SpringBoot的配置原理

這個(gè)注解的作用就是

1.開(kāi)啟Car的屬性配置功能

2.把這個(gè)Car這個(gè)組件自動(dòng)注冊(cè)到容器中

再次運(yùn)行程序,可以得到相同的結(jié)果

java進(jìn)階之了解SpringBoot的配置原理

四、自動(dòng)配置原理

說(shuō)完上面這些,我們來(lái)看一下,Spring Boot是如何實(shí)現(xiàn)自動(dòng)裝配的

引導(dǎo)加載自動(dòng)配置類

我們先點(diǎn)進(jìn)@SpringBootApplication的源碼中去,發(fā)現(xiàn)它其實(shí)是3個(gè)注解的合成注解:

@SpringBootConfiguration @EnableAutoConfiguration @ComponentScan

java進(jìn)階之了解SpringBoot的配置原理

@SpringBootConfiguration

其中,@SpringBootConfiguration的源碼底層使用了@Configuration注解,說(shuō)明它其實(shí)也是一個(gè)配置類,只不過(guò)它相當(dāng)于是一個(gè)主配置。

@ComponentScan

根據(jù)我們之前的學(xué)習(xí),這個(gè)注解其實(shí)就是一個(gè)組件掃描器的作用,是Spring的注解

@EnableAutoConfiguration(核心)

最關(guān)鍵最核心的注解就是這個(gè),@EnableAutoConfiguration

@AutoConfigurationPackage

我們點(diǎn)進(jìn)它的源碼里面去,發(fā)現(xiàn)它底層調(diào)用了一個(gè)叫@AutoConfigurationPackage的注解,翻譯過(guò)來(lái)就是自動(dòng)配置包,它指定了默認(rèn)的包規(guī)則

java進(jìn)階之了解SpringBoot的配置原理

再繼續(xù)查看它的底層源碼,發(fā)現(xiàn)它導(dǎo)入了一個(gè)叫Register的組件

java進(jìn)階之了解SpringBoot的配置原理

點(diǎn)進(jìn)去,給它打上一個(gè)斷點(diǎn),來(lái)看一下到底是如何運(yùn)作的

java進(jìn)階之了解SpringBoot的配置原理

代碼現(xiàn)在在這里停住了,讓我們來(lái)看一下這一行代碼里面,發(fā)現(xiàn)它能夠找到我們所在的包名,由此我們也就能知道為什么 Spring Boot 能夠?qū)⒅付ǖ囊粋€(gè)包下的所有組件導(dǎo)入進(jìn)來(lái)了,

java進(jìn)階之了解SpringBoot的配置原理

@Import({AutoConfigurationImportSelector.class})

@EnableAutoConfiguration注解下還有一個(gè)注解,它是干什么的呢?讓我們看一下源碼就知道了

java進(jìn)階之了解SpringBoot的配置原理

在AutoConfigurationImportSelector類下面我們找到了一個(gè)方法getAutoConfigurationEntry(annotationMetadata),它是用來(lái)給容器中批量導(dǎo)入一些組件的

java進(jìn)階之了解SpringBoot的配置原理

給他打一個(gè)斷點(diǎn),看看到底加入了些什么組件進(jìn)容器里

java進(jìn)階之了解SpringBoot的配置原理

說(shuō)明這 131 個(gè)對(duì)象都是要加入到容器中的,并且都存儲(chǔ)在了一個(gè)List集合當(dāng)中 List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes)

java進(jìn)階之了解SpringBoot的配置原理

為什么會(huì)是131個(gè)呢? 其實(shí)是Spring Boot 里面寫死了,一啟動(dòng)就要給容器中加載的所有配置類

打開(kāi)spring-boot-autoconfigure-2.5.0.RELEASE.jar下META-INF/spring.factories位置的文件,讓我們來(lái)看一下源碼是怎么寫的

java進(jìn)階之了解SpringBoot的配置原理

這里寫了一大堆 xxxxAutoConfiguration 的配置類,從26行開(kāi)始,到156行結(jié)束,剛好是 131 個(gè)。

java進(jìn)階之了解SpringBoot的配置原理java進(jìn)階之了解SpringBoot的配置原理

雖然我們 131 個(gè)場(chǎng)景的所有自動(dòng)配置啟動(dòng)的時(shí)候默認(rèn)全部加載,但并不是都會(huì)生效的,比如 AOP 的部分功能就需要你導(dǎo)入 aspectj 相關(guān)的包才能生效。它是按照條件裝配規(guī)則(@Conditional),最終會(huì)按需配置。

如圖, aspectj 是爆紅的

java進(jìn)階之了解SpringBoot的配置原理

除了AOP之外,還有一些類也是沒(méi)有生效的(比如CacheAutoConfiguration),這里就不再贅述了,感興趣的同學(xué)可以去看源碼了解一下。

五、修改默認(rèn)配置(約定大于配置)

SpringBoot 默認(rèn)會(huì)在底層配好所有的組件。但是如果用戶自己配置了以用戶的優(yōu)先

以 SpringMVC 中的文件上傳解析器為例,他在容器中的默認(rèn)名字是multipartResolver,但是我們寫代碼的時(shí)候可能不知道底層源碼里面給他的默認(rèn)名字是這個(gè),我們給他起了另外一個(gè)名字,這個(gè)時(shí)候 SpringBoot 就會(huì)去容器中找到你所配置的那個(gè)組件,并且返回那個(gè)組件,也就是下面這段代碼:

java進(jìn)階之了解SpringBoot的配置原理

這是為了防止有些用戶配置的文件上傳解析器不符合規(guī)范。

六、總結(jié) SpringBoot先加載所有的自動(dòng)配置類 xxxxxAutoConfiguration 每個(gè)自動(dòng)配置類按照條件進(jìn)行生效,默認(rèn)都會(huì)綁定配置文件指定的值。xxxxProperties里面拿。xxxProperties和配置文件進(jìn)行了綁定 生效的配置類就會(huì)給容器中裝配很多組件 只要容器中有這些組件,相當(dāng)于這些功能就有了 定制化配置 用戶直接自己@Bean替換底層的組件 用戶去看這個(gè)組件是獲取的配置文件什么值就去修改。

整個(gè)的流程:xxxxxAutoConfiguration —> 組件 —> xxxxProperties里面拿值 ----> application.properties

所以,當(dāng)我們需要修改組件的配置的時(shí)候,只需要在application.properties里面進(jìn)行配置即可

到此這篇關(guān)于java進(jìn)階之了解SpringBoot的配置原理的文章就介紹到這了,更多相關(guān)SpringBoot的配置原理內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Java
相關(guān)文章:
主站蜘蛛池模板: 星子县| 通辽市| 留坝县| 宽城| 南京市| 白水县| 聂拉木县| 额敏县| 娱乐| 赤峰市| 阳曲县| 翁牛特旗| 定襄县| 萍乡市| 喀喇| 湘阴县| 上犹县| 莫力| 磐安县| 玉树县| 兖州市| 扶余县| 连平县| 昭觉县| 诸暨市| 那坡县| 许昌县| 中山市| 自治县| 周至县| 报价| 长春市| 嵊泗县| 二连浩特市| 仁寿县| 威信县| 武宣县| 长春市| 西吉县| 镇安县| 泸西县|