




版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
第Spring中@order注解用法實(shí)戰(zhàn)教程目錄前言一、觀察@order源碼二、@order實(shí)戰(zhàn)三、@order失效原因四、解決排序問(wèn)題五、排序源碼分析六、@AutoConfigureOrder總結(jié)
前言
@order注解是spring-core包下的一個(gè)注解,@Order的作用是定義SpringIOC容器中Bean的執(zhí)行順序的優(yōu)先級(jí)(這里的順序也可以理解為存放到容器中的先后順序)。開(kāi)發(fā)過(guò)程當(dāng)中有時(shí)候經(jīng)常會(huì)出現(xiàn)配置依賴關(guān)系,例如注入A對(duì)象使用了
@ConditionalOnBean(B.class),意思是要求容器當(dāng)中必須存在B.class的實(shí)例的時(shí)候,才會(huì)進(jìn)行注入A。這時(shí)候我們就必須保證B對(duì)象在注入A對(duì)象前進(jìn)行注入。
一、觀察@order源碼
(1)源碼當(dāng)中有三個(gè)元注解:
@Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD}):使用范圍接口、類(lèi)、枚舉、注解、方法、字段@Retention(RetentionPolicy.RUNTIME):@Retention是用來(lái)修飾注解的生命周期的,RetentionPolicy.RUNTIME代表的是不僅被保存到class文件中,jvm加載class文件之后,仍然存在;一直有效!@Documented:@Documented和@Deprecated注解長(zhǎng)得有點(diǎn)像,@Deprecated是用來(lái)標(biāo)注某個(gè)類(lèi)或者方法不建議再繼續(xù)使用,@Documented只能用在注解上,如果一個(gè)注解@B,被@Documented標(biāo)注,那么被@B修飾的類(lèi),生成Javadoc文檔時(shí),會(huì)顯示@B。
(2)屬性:
@order當(dāng)中只要一個(gè)value屬性,而且還是int類(lèi)型,值越低優(yōu)先級(jí)越高,默認(rèn)值是Ordered.LOWEST_PRECEDENCE,表示最低優(yōu)先級(jí)(輸給任何其他指定的順序值)。
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})
@Documented
public@interfaceOrder{
intvalue()default2147483647;
官網(wǎng)注釋:/spring-projects/spring-framework/blob/main/spring-core/src/main/java/org/springframework/core/annotation/Order.java
二、@order實(shí)戰(zhàn)
(1)自定義兩個(gè)配置類(lèi)
我們要求Config2先進(jìn)行加載,然后通過(guò)@order來(lái)排序測(cè)試一下
@Configuration
publicclassConfig1{
publicConfig1(){
System.out.println("Config1構(gòu)建了");
@Configuration
publicclassConfig2{
publicConfig2(){
System.out.println("Config2構(gòu)建了");
(2)啟動(dòng)項(xiàng)目測(cè)試:默認(rèn)是先創(chuàng)建的Config1后創(chuàng)建的Config2
(3)既然order可以控制加載順序,那我們來(lái)試驗(yàn)一下,然后讓Config2先加載
@Configuration
@Order(2)
publicclassConfig1{
publicConfig1(){
System.out.println("Config1構(gòu)建了");
@Configuration
@Order(1)
publicclassConfig2{
publicConfig2(){
System.out.println("Config2構(gòu)建了");
但是好像沒(méi)什么卵用
(4)分析原因
目前這兩個(gè)是在同包情況下不起作用。
于是進(jìn)行分開(kāi)了
分開(kāi)之后竟然生效了
(5)但是分開(kāi)也是將Config2放到了上面的包當(dāng)中,于是我又改成了Config1放到最上面,這樣進(jìn)行測(cè)試,結(jié)果又失效了
(6)于是我又放在了同包下,將Config2命名為A開(kāi)頭的,這樣他就放到了最上面,于是這樣同樣也生效了。
期間我還嘗試著將@Configuration都改為使用@Component,結(jié)果仍然不變。
得出結(jié)論:@order指定加載順序還跟類(lèi)的命名和存放位置有關(guān)!假如有Config1和Config2兩個(gè)類(lèi)在一個(gè)包下,要求是Config2先加載:
這時(shí)候設(shè)置Config2的@order值就算是小于Config1的@order值同樣也是Config1先加載。如果同包情況下可以重新命名Config2,只要在Config1上面就行?;蛘卟痖_(kāi)不同包也可以,但是Config2所在的包也必須比Config1所呆的包上面。
這樣才能保證@Order生效!
三、@order失效原因
https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-constructor-injection
最關(guān)鍵的一句話:您可以在目標(biāo)類(lèi)級(jí)別和@Bean方法上聲明@Order注釋,可能針對(duì)的是單個(gè)bean定義(如果多個(gè)定義使用同一個(gè)bean類(lèi))。@Order值可能會(huì)影響注入點(diǎn)的優(yōu)先級(jí),但請(qǐng)注意,它們不會(huì)影響單例啟動(dòng)順序,這是由依賴關(guān)系和@DependsOn聲明確定的正交關(guān)注。
我理解的注入點(diǎn)的優(yōu)先級(jí)應(yīng)該是指的存放容器的先后順序,也就是他并不會(huì)影響啟動(dòng)順序。
四、解決排序問(wèn)題
我們不可能每次遇到這種問(wèn)題又是改名又是換包的,所以,springboot提供了如下三個(gè)注解可以控制順序:
@AutoConfigureAfter:當(dāng)前配置類(lèi)在指定配置類(lèi)之后執(zhí)行@AutoConfigureBefore:當(dāng)前配置類(lèi)在指定配置類(lèi)之前執(zhí)行@AutoConfigureOrder:指定優(yōu)先級(jí),數(shù)值越小,優(yōu)先級(jí)越高。
(1)首先將代碼改回原來(lái)的樣子
(2)在Config2使用@AutoConfigureBefore(Config1.class),代表的是在config1加載前進(jìn)行加載
@Configuration
publicclassConfig1{
publicConfig1(){
System.out.println("Config1構(gòu)建了");
@Configuration
@AutoConfigureBefore(Config1.class)
publicclassConfig2{
publicConfig2(){
System.out.println("Config2構(gòu)建了");
(3)輸出結(jié)果,顯然還是沒(méi)生效
可能有時(shí)候走了運(yùn)給你一種錯(cuò)覺(jué)還真的配置成功了。實(shí)際上這種方式是不可行的,以上三個(gè)注解只有針對(duì)自動(dòng)配置類(lèi)才會(huì)生效。
在autoconfigure包下就有spring.factories,這個(gè)文件配置了自動(dòng)配置類(lèi),springboot會(huì)讀取這個(gè)文件的,我們也可以在自己項(xiàng)目上定義spring.factories,這樣我們的配置類(lèi)對(duì)于@AutoConfigureAfter注解就可以生效了。
(4)自定義spring.factories
第一行是固定的,后面的就是全類(lèi)名,雖然只有Config2使用了注解,但是需求是和Config1進(jìn)行排序,所以這兩個(gè)都得加。
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
.springbootcache.config.Config2,\
.springbootcache.config.Config1
(5)測(cè)試,成功解決
五、排序源碼分析
針對(duì)于@AutoConfigure那三個(gè)注解原理:其實(shí)關(guān)鍵的代碼還是在AutoConfigurationImportSelector中,將自動(dòng)配置類(lèi)從spring.factories加載出來(lái)之后會(huì)根據(jù)條件排序(只有自動(dòng)配置類(lèi)!),在selectImports()方法中最后一行代碼如下:
緊接著會(huì)走到這個(gè)地方,實(shí)際上是分了三步排序:
先按照文件名字母排序按照@AutoConfigureOrder進(jìn)行排序按照@AutoConfigureBefore和@AutoConfigureAfter排序
從上面配置的順序可以知道,最終決定權(quán)還是在@AutoConfigureAfter、@AutoConfigureBefore這兩個(gè)注解。
當(dāng)我們不設(shè)置spring.factories的時(shí)候,這里面壓根都沒(méi)有這兩個(gè)類(lèi)!
六、@AutoConfigureOrder
這種也是可以的!當(dāng)然前提也是需要配置spring.factories
@Configuration
@AutoConfigureOrder(
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 奧鵬網(wǎng)絡(luò)安全
- 光伏防火培訓(xùn)課件
- 運(yùn)費(fèi)清算協(xié)議書(shū)模板
- 海邊安全協(xié)議書(shū)
- 鄉(xiāng)村特色產(chǎn)業(yè)扶貧協(xié)議
- 釘釘辦公軟件培訓(xùn)
- 遺失車(chē)位協(xié)議書(shū)范本
- 退款協(xié)議回收合同模板
- 房地產(chǎn)分銷(xiāo)服務(wù)合同
- 骨科手術(shù)的圍手術(shù)期疼痛管理
- 包車(chē)客運(yùn)可行性方案
- DB32/T+4638-2024+智能泵站技術(shù)導(dǎo)則
- 圖書(shū)館消防安全培訓(xùn)課件
- 800萬(wàn)噸年混合原油常減壓蒸裝置設(shè)計(jì)
- 學(xué)習(xí)科學(xué)研究與方法論
- 扁鵲治病課本劇劇本
- PCT申請(qǐng)進(jìn)入國(guó)家階段的程序及實(shí)務(wù)操作
- 教師教學(xué)中分層布置作業(yè)現(xiàn)狀的調(diào)查問(wèn)卷
- 招商引資培訓(xùn)課件-招商引資講課
- 走進(jìn)神奇的中藥學(xué)習(xí)通章節(jié)答案期末考試題庫(kù)2023年
評(píng)論
0/150
提交評(píng)論