SpringBoot中@Conditional注解的使用
1、基本介紹
- @Conditional注解是一個(gè)條件裝配注解,主要用于限制@Bean注解在什么時(shí)候才生效。以指定的條件形式控制bean的創(chuàng)建
- @Conditional可以自定義條件進(jìn)行裝配或者不裝配…
- @Conditional本身還是一個(gè)父注解,派生出大量的子注解;可以按需加載!
- 因此在學(xué)習(xí)SpringBoot的時(shí)候是非常有必要學(xué)習(xí)這個(gè)注解的使用的,SpringBoot就是按需加載。
- Conditional注解和所有子注解首先必須依托@Configuration配置類(lèi)注解
- 都可以加載類(lèi)或者方法上;加載類(lèi)上的含義所有的方法都按照這個(gè)條件裝配、加載方法上只有該方法進(jìn)行條件裝配。
- 注:Conditional注解是Spring4.0就有的,旗下的子注解是SpringBoot1.0有的。
2、@Conditional注解
使用Conditional注解進(jìn)行條件裝配時(shí)需要自定義類(lèi)實(shí)現(xiàn)Condition接口(spring包下的,不是JUC包下)
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
// 自定義類(lèi)實(shí)現(xiàn)Condition接口,完成給出指定的條件。
Class<? extends Condition>[] value();
}2.1、自定義條件
如果存在dog1則不會(huì)對(duì)條件裝配bean進(jìn)行創(chuàng)建。
public class MyCondition implements Condition {
/**
* @param context: 判斷條件使用的上下文環(huán)境
* @param metadata: 掃描的注解信息
*/
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
// 1. 獲取bean工廠
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
// 2. 獲取運(yùn)行環(huán)境, 可以根據(jù)操作系統(tǒng)的環(huán)境進(jìn)行限制bean
Environment environment = context.getEnvironment();
// 3. 獲取BeanDefinition注冊(cè)定義表
context.getRegistry();
// 4. 獲取資源加載器
context.getResourceLoader();
// 5. 獲取類(lèi)加載器
ClassLoader classLoader = context.getClassLoader();
if (beanFactory.containsBean("dog1")) {
return false;
}
/**
* 可以根據(jù)以上條件進(jìn)行條件裝配
* true: 裝配
* false: 不裝配
*/
return true;
}
}2.2、條件裝配測(cè)試
@Configuration
public class MyConfig {
@Bean("user1")
public User user1(){
return new User("splay", 22, "男");
}
@Bean("dog1")
//@ConditionalOnBean(name = {"dog2"})
public Dog dog1(){
return new Dog("金毛", 4,"公");
}
@Bean("dog2")
@Conditional(value = MyCondition.class)
public Dog dog2(){
return new Dog("拉布拉多", 3,"母");
}
}在dog2上加上條件裝配,當(dāng)掃描到這個(gè)bean時(shí)會(huì)進(jìn)行條件判斷。

3、@ConditionalOnBean子注解
子注解其實(shí)也是Conditional注解的特定裝配,只不過(guò)條件類(lèi)已經(jīng)實(shí)現(xiàn)好了。
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnBeanCondition.class) //OnBeanCondition是一個(gè)Condition接口的實(shí)現(xiàn)類(lèi)
public @interface ConditionalOnBean {
// 1. 按照bean的類(lèi)型進(jìn)行檢查
Class<?>[] value() default {};
// 2. 按照bean的類(lèi)型進(jìn)行檢查
String[] type() default {};
// 3. 按照bean的注解進(jìn)行檢查
Class<? extends Annotation>[] annotation() default {};
// 4. 按照BeanName進(jìn)行檢查
String[] name() default {};
// 5. 搜索策略
SearchStrategy search() default SearchStrategy.ALL;
// 6. 不詳
Class<?>[] parameterizedContainer() default {};
}
3.1、條件裝配測(cè)試(一)
當(dāng)容器中存在dog1的時(shí)候在創(chuàng)建dog2,否則就不會(huì)進(jìn)行創(chuàng)建。
@Configuration
public class MyConfig {
@Bean("user1")
public User user1(){
return new User("splay", 22, "男");
}
@Bean("dog1")
public Dog dog1(){
return new Dog("金毛", 4,"公");
}
@Bean("dog2")
@ConditionalOnBean(name = {"dog1"})
public Dog dog2(){
return new Dog("拉布拉多", 3,"母");
}
}

3.2、條件裝配測(cè)試(二)
在使用時(shí)發(fā)現(xiàn)條件裝配與bean的編寫(xiě)注冊(cè)順序有關(guān)系,如果先后順序?qū)е聦?huì)出現(xiàn)失敗的情況。
@Configuration
public class MyConfig {
@Bean("user1")
public User user1(){
return new User("splay", 22, "男");
}
@Bean("dog1")
@ConditionalOnBean(name = {"dog2"}) //當(dāng)有dog2組件的時(shí)候創(chuàng)建dog1
public Dog dog1(){
return new Dog("金毛", 4,"公");
}
@Bean("dog2")
public Dog dog2(){
return new Dog("拉布拉多", 3,"母");
}
}

對(duì)比上面測(cè)試一發(fā)現(xiàn)dog1并沒(méi)有成功創(chuàng)建,猜測(cè)創(chuàng)建的時(shí)候估計(jì)是按照某種順序進(jìn)行的!
因此在使用條件裝配進(jìn)行創(chuàng)建的時(shí)候一定要注意唄依賴(lài)的條件是否要先創(chuàng)建的問(wèn)題!
到此這篇關(guān)于SpringBoot 中@Conditional注解的使用的文章就介紹到這了,更多相關(guān)@Conditional注解使用內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
springboot實(shí)現(xiàn)熱部署操作方法
這篇文章主要介紹了springboot實(shí)現(xiàn)熱部署操作方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-11-11
Java實(shí)現(xiàn)單鏈表SingleLinkedList增刪改查及反轉(zhuǎn) 逆序等
單鏈表是鏈表的其中一種基本結(jié)構(gòu)。一個(gè)最簡(jiǎn)單的結(jié)點(diǎn)結(jié)構(gòu)如圖所示,它是構(gòu)成單鏈表的基本結(jié)點(diǎn)結(jié)構(gòu)。在結(jié)點(diǎn)中數(shù)據(jù)域用來(lái)存儲(chǔ)數(shù)據(jù)元素,指針域用于指向下一個(gè)具有相同結(jié)構(gòu)的結(jié)點(diǎn)。 因?yàn)橹挥幸粋€(gè)指針結(jié)點(diǎn),稱(chēng)為單鏈表2021-10-10
解決spring結(jié)合mybatis時(shí)一級(jí)緩存失效的問(wèn)題
這篇文章主要介紹了解決spring結(jié)合mybatis時(shí)一級(jí)緩存失效的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-11-11
Spring?Boot實(shí)現(xiàn)文件上傳下載
這篇文章主要為大家詳細(xì)介紹了Spring?Boot實(shí)現(xiàn)文件上傳下載,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-08-08
idea配置檢查XML中SQL語(yǔ)法及書(shū)寫(xiě)sql語(yǔ)句智能提示的方法
idea連接了數(shù)據(jù)庫(kù),也可以執(zhí)行SQL查到數(shù)據(jù),但是無(wú)法識(shí)別sql語(yǔ)句中的表導(dǎo)致沒(méi)有提示,下面這篇文章主要給大家介紹了關(guān)于idea配置檢查XML中SQL語(yǔ)法及書(shū)寫(xiě)sql語(yǔ)句智能提示的相關(guān)資料,需要的朋友可以參考下2023-03-03
Java實(shí)現(xiàn)監(jiān)聽(tīng)UDP協(xié)議的指定端口并收到數(shù)據(jù)按照十六進(jìn)制輸出方式
這篇文章主要介紹了Java實(shí)現(xiàn)監(jiān)聽(tīng)UDP協(xié)議的指定端口并收到數(shù)據(jù)按照十六進(jìn)制輸出方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-04-04
Java實(shí)現(xiàn)斗地主與猜數(shù)字游戲詳細(xì)流程
這篇文章主要介紹了怎么用Java來(lái)寫(xiě)斗地主種洗牌和發(fā)牌的功能,以及猜數(shù)字的游戲,斗地主相信大家都知道,同時(shí)也知道每一局都要洗牌打亂順序再發(fā)牌,本篇我們就來(lái)實(shí)現(xiàn)它們能,感興趣的朋友跟隨文章往下看看吧2022-04-04

