SpringBoot中@Conditional注解的使用
1、基本介紹
- @Conditional注解是一個條件裝配注解,主要用于限制@Bean注解在什么時候才生效。以指定的條件形式控制bean的創(chuàng)建
- @Conditional可以自定義條件進行裝配或者不裝配…
- @Conditional本身還是一個父注解,派生出大量的子注解;可以按需加載!
- 因此在學習SpringBoot的時候是非常有必要學習這個注解的使用的,SpringBoot就是按需加載。
- Conditional注解和所有子注解首先必須依托@Configuration配置類注解
- 都可以加載類或者方法上;加載類上的含義所有的方法都按照這個條件裝配、加載方法上只有該方法進行條件裝配。
- 注:Conditional注解是Spring4.0就有的,旗下的子注解是SpringBoot1.0有的。
2、@Conditional注解
使用Conditional注解進行條件裝配時需要自定義類實現(xiàn)Condition接口(spring包下的,不是JUC包下)
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
// 自定義類實現(xiàn)Condition接口,完成給出指定的條件。
Class<? extends Condition>[] value();
}2.1、自定義條件
如果存在dog1則不會對條件裝配bean進行創(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. 獲取運行環(huán)境, 可以根據(jù)操作系統(tǒng)的環(huán)境進行限制bean
Environment environment = context.getEnvironment();
// 3. 獲取BeanDefinition注冊定義表
context.getRegistry();
// 4. 獲取資源加載器
context.getResourceLoader();
// 5. 獲取類加載器
ClassLoader classLoader = context.getClassLoader();
if (beanFactory.containsBean("dog1")) {
return false;
}
/**
* 可以根據(jù)以上條件進行條件裝配
* true: 裝配
* false: 不裝配
*/
return true;
}
}2.2、條件裝配測試
@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上加上條件裝配,當掃描到這個bean時會進行條件判斷。

3、@ConditionalOnBean子注解
子注解其實也是Conditional注解的特定裝配,只不過條件類已經實現(xiàn)好了。
@Target({ ElementType.TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(OnBeanCondition.class) //OnBeanCondition是一個Condition接口的實現(xiàn)類
public @interface ConditionalOnBean {
// 1. 按照bean的類型進行檢查
Class<?>[] value() default {};
// 2. 按照bean的類型進行檢查
String[] type() default {};
// 3. 按照bean的注解進行檢查
Class<? extends Annotation>[] annotation() default {};
// 4. 按照BeanName進行檢查
String[] name() default {};
// 5. 搜索策略
SearchStrategy search() default SearchStrategy.ALL;
// 6. 不詳
Class<?>[] parameterizedContainer() default {};
}
3.1、條件裝配測試(一)
當容器中存在dog1的時候在創(chuàng)建dog2,否則就不會進行創(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、條件裝配測試(二)
在使用時發(fā)現(xiàn)條件裝配與bean的編寫注冊順序有關系,如果先后順序導致將會出現(xiàn)失敗的情況。
@Configuration
public class MyConfig {
@Bean("user1")
public User user1(){
return new User("splay", 22, "男");
}
@Bean("dog1")
@ConditionalOnBean(name = {"dog2"}) //當有dog2組件的時候創(chuàng)建dog1
public Dog dog1(){
return new Dog("金毛", 4,"公");
}
@Bean("dog2")
public Dog dog2(){
return new Dog("拉布拉多", 3,"母");
}
}

對比上面測試一發(fā)現(xiàn)dog1并沒有成功創(chuàng)建,猜測創(chuàng)建的時候估計是按照某種順序進行的!
因此在使用條件裝配進行創(chuàng)建的時候一定要注意唄依賴的條件是否要先創(chuàng)建的問題!
到此這篇關于SpringBoot 中@Conditional注解的使用的文章就介紹到這了,更多相關@Conditional注解使用內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Java實現(xiàn)單鏈表SingleLinkedList增刪改查及反轉 逆序等
單鏈表是鏈表的其中一種基本結構。一個最簡單的結點結構如圖所示,它是構成單鏈表的基本結點結構。在結點中數(shù)據(jù)域用來存儲數(shù)據(jù)元素,指針域用于指向下一個具有相同結構的結點。 因為只有一個指針結點,稱為單鏈表2021-10-10
idea配置檢查XML中SQL語法及書寫sql語句智能提示的方法
idea連接了數(shù)據(jù)庫,也可以執(zhí)行SQL查到數(shù)據(jù),但是無法識別sql語句中的表導致沒有提示,下面這篇文章主要給大家介紹了關于idea配置檢查XML中SQL語法及書寫sql語句智能提示的相關資料,需要的朋友可以參考下2023-03-03
Java實現(xiàn)監(jiān)聽UDP協(xié)議的指定端口并收到數(shù)據(jù)按照十六進制輸出方式
這篇文章主要介紹了Java實現(xiàn)監(jiān)聽UDP協(xié)議的指定端口并收到數(shù)據(jù)按照十六進制輸出方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-04-04
Java實現(xiàn)斗地主與猜數(shù)字游戲詳細流程
這篇文章主要介紹了怎么用Java來寫斗地主種洗牌和發(fā)牌的功能,以及猜數(shù)字的游戲,斗地主相信大家都知道,同時也知道每一局都要洗牌打亂順序再發(fā)牌,本篇我們就來實現(xiàn)它們能,感興趣的朋友跟隨文章往下看看吧2022-04-04

