您好,登錄后才能下訂單哦!
這期內(nèi)容當(dāng)中小編將會給大家?guī)碛嘘P(guān)如何在java中配置SpringBoot,文章內(nèi)容豐富且以專業(yè)的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
首先我們要知道 Spring Boot 在底層已經(jīng)為我們添加好了很多依賴。比如我們常用的Tomcat,Spring,SpringMVC這些,甚至連mysql數(shù)據(jù)庫的依賴也為我們添加好了
不過 SpringBoot 2.5.0 使用的mysql依賴版本是8.0.25的,如果還在使用 mysql 5 版本的小伙伴們就需要在項(xiàng)目的 pom.xml 文件中再次指定自己所用的依賴版本號。(因?yàn)?maven 在引入依賴時采取就近原則,你如果指定了依賴版本號的話,它會加載離它近的,而不會去加載遠(yuǎn)的)
例如,我要修改 mysql 依賴的版本為5.1.43
//在當(dāng)前項(xiàng)目里面重寫配置 <properties> <mysql.version>5.1.43</mysql.version> </properties>
添加組件
@Configuration、@Bean注解
首先,這個注解是寫在類上面的,告訴 spring boot 這是一個配置類,等同于 以前的配置文件
配置類里面使用@Bean
標(biāo)注在方法上給容器注冊組件,默認(rèn)情況下是單例的。以方法名就是組件的 id 。返回類型就是組件類型。返回的值,就是組件在容器中的實(shí)例
為什么他會是單例的呢? 原因是在@Configuration
注解的源碼中,還定義了一個屬性proxyBeanMethods ,默認(rèn)值是 true。
當(dāng)然我們也可以修改他的值為false,這樣他就會創(chuàng)建多個對象了。
舉個例子:
我現(xiàn)在在配置類里面定義了一個組件,他會返回一個 User 對象,當(dāng)proxyBeanMethods = true
時,無論調(diào)用多少次 user01()
方法,在容器中都只會存在一個實(shí)例對象,但我現(xiàn)在把它改為 false
,來測試一下他到底是不是能創(chuàng)建多個實(shí)例了。
在主方法中進(jìn)行測試:
User user=config.user01(); User user1=config.user01(); System.out.println(user==user1);
最后輸出的結(jié)果是
false
這就說明現(xiàn)在創(chuàng)建了兩個對象了,在容器中user
和user1
并不是指向同一塊內(nèi)存地址
那我們什么時候可以把它改成 false 來使用呢? 這就要設(shè)計到兩種編寫Spring Boot的方式了
一種是FULL模式 全模式(單例)
另一種是Lite模式 輕量級模式(非單例)
如果有組件依賴必須使用Full模式(默認(rèn))。其他默認(rèn)是否Lite模式
Import注解
加入 IOC 容器的方式有很多種,上面的@Bean
是一種,這里提到的@Import
也是用來注冊組件的,@Import
注解可以用于導(dǎo)入第三方包 (當(dāng)然@Bean
也可以)
它是寫在類上面的,
它所創(chuàng)建的組件 id 默認(rèn)是類的全限定名稱
具體用法參考:b站Spring注解驅(qū)動教程
Conditional注解
條件裝配:滿足Conditional指定的條件,則進(jìn)行組件注入
@Conditional
注解下面還有許多的子注解
因?yàn)樗淖幼⒔鈱?shí)在太多了,下面我們具體實(shí)現(xiàn)一個例子來說明一下它的功能
先在 User 類中再加入一個 Pet 屬性
現(xiàn)在我希望容器在沒有 Pet 的情況下,我也不要 User 對象
要實(shí)現(xiàn)這個需求,可以這樣做,在 User 組件前面添加@ConditionalOnBean
注解,并指定條件為 Pet 組件的 id 來進(jìn)行限制
執(zhí)行測試方法
運(yùn)行結(jié)果:
容器中是否有tomcat:false
容器中是否有user:false
這樣就對組件 User 的注冊加以限制了
也可以把@ConditionalOnBean(name="tom")
注解加在配置類上面,當(dāng)容器中有 tom 組件時,這個類中的其他組件才會生效,否則不生效
如果你原有的項(xiàng)目還是使用 beans.xml 等配置文件的方式來注冊組件的話,SpringBoot 是肯定無法自動配置的,那怎么樣才能讓SpringBoot用我這個配置文件去注冊組件呢?
@ImportResource注解
使用@ImportResource
注解可以引入以前那種 xml 配置文件的方式寫的組件
使用方法:直接加在現(xiàn)在的配置類上面,例如:
@ImportResource("classpath:beans.xml")
配置綁定
配置綁定是什么意思呢?其實(shí)就是使用Java讀取到properties文件中的內(nèi)容,并且把它封裝到JavaBean中,以供隨時使用
具體做法:使用@ConfigurationProperties
注解
這個注解是加在你需要從 properties 屬性配置文件中要導(dǎo)入的屬性的類上面。
比如:我現(xiàn)在寫了一個 Car 類,然后在 properties 文件中寫好了它的屬性
( 注意:properties 文件中的所有屬性均要小寫,駝峰命名法也不行,可以用 - 或 _ 來代替 )
我們想要將配置文件中定義好的屬性綁定到實(shí)例對象上的話,就可以在 Car 這個類上面加上@ConfigurationProperties(prefix = "mycar")
,prefix
代表前綴的意思。
單加上這一個注解還不行,因?yàn)榇藭r容器中還沒有這個對象,可以采用兩種方式來把 Car 這個對象加入容器中:
1.使用@Component注解
2.使用@EnableConfigurationProperties注解
@Component+@ConfigurationProperties
在@ConfigurationProperties
注解上方加上@Component
注解,即可將 Car 加入到容器中
測試方法:
運(yùn)行,訪問 “/car” 查看結(jié)果
@EnableConfigurationProperties+@ConfigurationProperties
使用@EnableConfigurationProperties
注解則需要在配置類上面添加,而不是 Car 上面
這個注解的作用就是
1.開啟Car的屬性配置功能
2.把這個Car這個組件自動注冊到容器中
再次運(yùn)行程序,可以得到相同的結(jié)果
說完上面這些,我們來看一下,Spring Boot是如何實(shí)現(xiàn)自動裝配的
引導(dǎo)加載自動配置類
我們先點(diǎn)進(jìn)@SpringBootApplication
的源碼中去,發(fā)現(xiàn)它其實(shí)是3個注解的合成注解:
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
@SpringBootConfiguration
其中,@SpringBootConfiguration
的源碼底層使用了@Configuration
注解,說明它其實(shí)也是一個配置類,只不過它相當(dāng)于是一個主配置。
@ComponentScan
根據(jù)我們之前的學(xué)習(xí),這個注解其實(shí)就是一個組件掃描器的作用,是Spring的注解
@EnableAutoConfiguration(核心)
最關(guān)鍵最核心的注解就是這個,@EnableAutoConfiguration
@AutoConfigurationPackage
我們點(diǎn)進(jìn)它的源碼里面去,發(fā)現(xiàn)它底層調(diào)用了一個叫@AutoConfigurationPackage
的注解,翻譯過來就是自動配置包,它指定了默認(rèn)的包規(guī)則
再繼續(xù)查看它的底層源碼,發(fā)現(xiàn)它導(dǎo)入了一個叫Register
的組件
點(diǎn)進(jìn)去,給它打上一個斷點(diǎn),來看一下到底是如何運(yùn)作的
代碼現(xiàn)在在這里停住了,讓我們來看一下這一行代碼里面,發(fā)現(xiàn)它能夠找到我們所在的包名,由此我們也就能知道為什么 Spring Boot 能夠?qū)⒅付ǖ囊粋€包下的所有組件導(dǎo)入進(jìn)來了,
@Import({AutoConfigurationImportSelector.class})
@EnableAutoConfiguration
注解下還有一個注解,它是干什么的呢?讓我們看一下源碼就知道了
在AutoConfigurationImportSelector
類下面我們找到了一個方法getAutoConfigurationEntry(annotationMetadata)
,它是用來給容器中批量導(dǎo)入一些組件的
給他打一個斷點(diǎn),看看到底加入了些什么組件進(jìn)容器里
說明這 131 個對象都是要加入到容器中的,并且都存儲在了一個List集合當(dāng)中 List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes)
為什么會是131個呢? 其實(shí)是Spring Boot 里面寫死了,一啟動就要給容器中加載的所有配置類
打開spring-boot-autoconfigure-2.5.0.RELEASE.jar下META-INF/spring.factories
位置的文件,讓我們來看一下源碼是怎么寫的
這里寫了一大堆 xxxxAutoConfiguration 的配置類,從26行開始,到156行結(jié)束,剛好是 131 個。
雖然我們 131 個場景的所有自動配置啟動的時候默認(rèn)全部加載,但并不是都會生效的,比如 AOP 的部分功能就需要你導(dǎo)入 aspectj 相關(guān)的包才能生效。它是按照條件裝配規(guī)則(@Conditional
),最終會按需配置。
如圖, aspectj 是爆紅的
除了AOP之外,還有一些類也是沒有生效的(比如CacheAutoConfiguration
),這里就不再贅述了,感興趣的同學(xué)可以去看源碼了解一下。
SpringBoot 默認(rèn)會在底層配好所有的組件。但是如果用戶自己配置了以用戶的優(yōu)先
以 SpringMVC 中的文件上傳解析器為例,他在容器中的默認(rèn)名字是multipartResolver
,但是我們寫代碼的時候可能不知道底層源碼里面給他的默認(rèn)名字是這個,我們給他起了另外一個名字,這個時候 SpringBoot 就會去容器中找到你所配置的那個組件,并且返回那個組件,也就是下面這段代碼:
這是為了防止有些用戶配置的文件上傳解析器不符合規(guī)范。
SpringBoot先加載所有的自動配置類 xxxxxAutoConfiguration
每個自動配置類按照條件進(jìn)行生效,默認(rèn)都會綁定配置文件指定的值。xxxxProperties里面拿。xxxProperties和配置文件進(jìn)行了綁定
生效的配置類就會給容器中裝配很多組件
只要容器中有這些組件,相當(dāng)于這些功能就有了
定制化配置
用戶直接自己@Bean替換底層的組件
用戶去看這個組件是獲取的配置文件什么值就去修改。
上述就是小編為大家分享的如何在java中配置SpringBoot了,如果剛好有類似的疑惑,不妨參照上述分析進(jìn)行理解。如果想知道更多相關(guān)知識,歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。