最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring IoC實現(xiàn)條件化裝配Bean的方法詳解

 更新時間:2025年07月10日 08:22:22   作者:冰糖心書房  
條件化裝配 Bean(Conditional Bean Assembly) 指的是:讓 Spring 容器根據(jù)特定的條件來決定是否要創(chuàng)建和注冊某一個 Bean,本文給大家介紹了Spring IoC實現(xiàn)條件化裝配Bean的詳細步驟,需要的朋友可以參考下

條件化裝配 Bean(Conditional Bean Assembly) 指的是:讓 Spring 容器根據(jù)特定的條件來決定是否要創(chuàng)建和注冊某一個 Bean。

這就像一個智能工廠的生產(chǎn)線,可以根據(jù)客戶的訂單(條件)來決定是安裝汽油引擎還是電動機。這個機制是 Spring Boot 自動配置(Auto-configuration)的基石。

核心武器:@Conditional 注解

所有條件化裝配都源于 Spring 4.0 引入的 @Conditional 注解。它是一個元注解,意思是它可以被用在其他注解上。

它的工作原理是:
@Conditional 注解需要一個 Condition 接口的實現(xiàn)類。在這個實現(xiàn)類中,你可以編寫任意邏輯來判斷條件是否滿足。如果滿足(返回 true),則被注解的 Bean 會被創(chuàng)建;如果不滿足(返回 false),則被忽略。

// 這是一個自定義的條件
public class MyCustomCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        // 在這里編寫你的判斷邏輯
        // 比如,檢查某個環(huán)境變量是否存在
        return System.getenv("MY_APP_MODE") != null;
    }
}

// 在配置類或Bean方法上使用
@Configuration
@Conditional(MyCustomCondition.class) // <-- 只有當條件滿足時,這個配置類及其所有Bean才生效
public class MySpecialConfiguration {
    @Bean
    public MyService myService() {
        return new MyService();
    }
}

雖然 @Conditional 很強大,但每次都自己寫一個 Condition 類比較繁瑣。因此,Spring Boot 在此基礎上,提供了一套開箱即用的、更具體的條件注解,覆蓋了 99% 的日常場景。

Spring Boot 提供的常用條件注解

這些注解通常用在 @Bean 方法上或 @Configuration 類上。

1. @ConditionalOnProperty (最常用)

條件:當配置文件(application.propertiesapplication.yml)中某個屬性的值滿足指定條件時。

場景:通過一個配置項來控制某個功能的開啟或關(guān)閉。

// application.properties
// a. 開啟短信通知
notification.service.type=sms 
// b. 開啟某個高級功能
feature.x.enabled=true
// 只有當 notification.service.type 的值是 "sms" 時,才創(chuàng)建 SmsService 這個 Bean
@Bean
@ConditionalOnProperty(name = "notification.service.type", havingValue = "sms")
public NotificationService smsService() {
    return new SmsService();
}

// 只有當 feature.x.enabled 的值是 "true" 時,才創(chuàng)建 FeatureX Bean
// matchIfMissing = true 表示如果配置文件里根本沒寫這個屬性,也算作條件滿足(即默認開啟)
@Bean
@ConditionalOnProperty(name = "feature.x.enabled", havingValue = "true", matchIfMissing = true)
public FeatureX featureX() {
    return new FeatureX();
}

2. @ConditionalOnBean 和 @ConditionalOnMissingBean

條件:當 IoC 容器中存在(或不存在)某個類型的 Bean 時。

這是實現(xiàn)“默認實現(xiàn)”和“用戶可覆蓋”模式的利器。

場景:你提供一個默認的緩存實現(xiàn)(如內(nèi)存緩存),但允許用戶自己定義一個 Redis 緩存 Bean 來覆蓋它。

@Configuration
public class CacheAutoConfiguration {

    // **關(guān)鍵**:只有當容器中不存在任何 CacheService 類型的 Bean 時,
    // 才創(chuàng)建下面這個默認的 InMemoryCacheService。
    @Bean
    @ConditionalOnMissingBean(CacheService.class)
    public CacheService inMemoryCache() {
        System.out.println("No custom cache found. Creating default InMemoryCache.");
        return new InMemoryCacheService();
    }
}

// 在用戶的配置中:
// 如果用戶自己定義了下面這個 Bean...
// @Configuration
// public class MyCacheConfig {
//     @Bean
//     public CacheService redisCache() {
//         return new RedisCacheService(); // 用戶自定義的實現(xiàn)
//     }
// }
// ...那么上面的 InMemoryCacheService 就不會被創(chuàng)建。

@ConditionalOnBean 則相反,表示只有當容器中已經(jīng)存在某個 Bean 時,才創(chuàng)建當前 Bean。這常用于配置依賴于其他組件的 Bean。

3. @ConditionalOnClass 和 @ConditionalOnMissingClass

條件:當應用的 classpath 中存在(或不存在)某個類時。

這是編寫 starter 模塊的核心。一個功能模塊通常依賴于某些第三方庫,只有當用戶引入了這些庫,相關(guān)的功能 Bean 才應該被創(chuàng)建。

場景:只有當用戶在 pom.xml 中引入了 mysql-connector-java 驅(qū)動包時,才自動配置一個 MySQL 相關(guān)的 Bean。

@Configuration
// 只有當 classpath 中能找到 "com.mysql.cj.jdbc.Driver" 這個類時,
// 這個配置才會生效。
@ConditionalOnClass(name = "com.mysql.cj.jdbc.Driver")
public class MySqlRelatedConfiguration {
    
    @Bean
    public MySqlHealthIndicator mySqlHealthIndicator() {
        // 創(chuàng)建一個檢查 MySQL 健康狀態(tài)的 Bean
        return new MySqlHealthIndicator();
    }
}

4. @ConditionalOnWebApplication 和 @ConditionalOnNotWebApplication

條件:判斷當前應用是否是一個 Web 應用(例如,classpath 中有 Spring MVC 或 WebFlux)。

場景:某些 Bean(如 Filter, Interceptor, WebMvcConfigurer)只在 Web 環(huán)境下才有意義。

@Configuration
@ConditionalOnWebApplication // 只有是Web應用時才生效
public class WebSpecificConfig {

    @Bean
    public MyCustomFilter myCustomFilter() {
        return new MyCustomFilter();
    }
}

綜合示例:智能通知服務

假設我們要構(gòu)建一個通知服務,默認使用郵件,但如果用戶配置了短信,則優(yōu)先使用短信。

// 1. application.properties (用戶可以不配置,或配置為sms)
// notification.channel=sms

// 2. 核心配置類
@Configuration
public class NotificationAutoConfiguration {

    // 方案A:如果用戶配置了短信渠道,創(chuàng)建 SmsService
    @Bean
    @ConditionalOnProperty(name = "notification.channel", havingValue = "sms")
    public NotificationService smsNotification() {
        System.out.println("Condition met: Creating SmsNotificationService.");
        return new SmsNotificationService();
    }

    // 方案B:如果容器里還沒有任何 NotificationService 的 Bean,
    // 就創(chuàng)建一個默認的 EmailService 作為“兜底”方案。
    @Bean
    @ConditionalOnMissingBean(NotificationService.class)
    public NotificationService emailNotification() {
        System.out.println("No other NotificationService found. Creating default EmailNotificationService.");
        return new EmailNotificationService();
    }
}

運行結(jié)果分析:

  • 如果用戶配置 notification.channel=smsSmsNotificationService 會被創(chuàng)建。因為此時容器中已經(jīng)有了 NotificationService 類型的 Bean,所以 EmailNotificationService@ConditionalOnMissingBean 條件不滿足,它不會被創(chuàng)建。最終注入的是 SmsNotificationService
  • 如果用戶沒有配置 notification.channelSmsNotificationService@ConditionalOnProperty 條件不滿足,它不會被創(chuàng)建。此時容器中沒有任何 NotificationService 類型的 Bean,所以 EmailNotificationService@ConditionalOnMissingBean 條件滿足,它會被創(chuàng)建。最終注入的是 EmailNotificationService。

總結(jié)

注解條件主要用途
@ConditionalOnProperty配置文件中屬性的值功能開關(guān),按配置切換實現(xiàn)
@ConditionalOnMissingBeanIoC 容器中缺少某個 Bean提供可被用戶覆蓋的默認實現(xiàn)(兜底 Bean)
@ConditionalOnBeanIoC 容器中存在某個 Bean當某個依賴準備好后,才裝配當前 Bean
@ConditionalOnClassClasspath 中存在某個類檢測是否引入了某個依賴庫,是開發(fā) starter 的核心
@ConditionalOnWebApplication當前是 Web 應用環(huán)境裝配只在 Web 環(huán)境下有意義的 Bean
@Conditional自定義 Condition實現(xiàn)高度定制化的、復雜的判斷邏輯

通過靈活運用這些條件注解,你就可以編寫出非常智能、健壯、可插拔的模塊,這也是 Spring Boot “約定優(yōu)于配置”理念的精髓所在。

到此這篇關(guān)于Spring IoC實現(xiàn)條件化裝配Bean的步驟詳解的文章就介紹到這了,更多相關(guān)Spring IoC條件化裝配Bean內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JAVA實現(xiàn)第三方短信發(fā)送過程詳解

    JAVA實現(xiàn)第三方短信發(fā)送過程詳解

    這篇文章主要介紹了JAVA實現(xiàn)第三方短信發(fā)送過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-09-09
  • MyBatis-Plus指定字段的查詢和排除過程

    MyBatis-Plus指定字段的查詢和排除過程

    文章介紹了如何在數(shù)據(jù)庫查詢中使用單個字段查詢、多個字段查詢、單個字段排除和多個字段排除,以及如何在實體類中使用注解進行排除
    2026-01-01
  • 在SpringBoot項目中獲取Request的四種方法

    在SpringBoot項目中獲取Request的四種方法

    這篇文章主要為大家詳細介紹了SpringBoot項目中獲取Request的四種方法,文中的示例代碼講解詳細,具有一定的參考價值,感興趣的小伙伴可以學習一下
    2023-11-11
  • Apache??Kafka安裝詳細教程

    Apache??Kafka安裝詳細教程

    Apache?Kafka?是一個分布式流處理平臺,被廣泛應用于大數(shù)據(jù)實時處理領(lǐng)域,本文將詳細介紹如何在集群環(huán)境中部署?Kafka?4.0.1?版本,感興趣的朋友跟隨小編一起看看吧
    2026-03-03
  • SpringBoot中數(shù)據(jù)傳輸對象(DTO)的實現(xiàn)

    SpringBoot中數(shù)據(jù)傳輸對象(DTO)的實現(xiàn)

    本文主要介紹了SpringBoot中數(shù)據(jù)傳輸對象(DTO)的實現(xiàn),包括了手動創(chuàng)建DTO、使用ModelMapper和Lombok創(chuàng)建DTO的示例,具有一定的參考價值,感興趣的可以了解一下
    2024-07-07
  • Java8的Optional如何干掉空指針(示例詳解)

    Java8的Optional如何干掉空指針(示例詳解)

    這篇文章主要介紹了Java8的Optional如何干掉空指針,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-01-01
  • springboot啟動不加載bootstrap.yml文件的問題

    springboot啟動不加載bootstrap.yml文件的問題

    這篇文章主要介紹了springboot啟動不加載bootstrap.yml文件的問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • 如何解決IDEA.properties文件中文亂碼問題

    如何解決IDEA.properties文件中文亂碼問題

    這篇文章主要介紹了如何解決IDEA.properties文件中文亂碼問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • Spring Data JPA調(diào)用存儲過程實例代碼

    Spring Data JPA調(diào)用存儲過程實例代碼

    本篇文章主要介紹了Spring Data JPA調(diào)用存儲過程實例代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下。
    2017-04-04
  • Spring條件注解@Conditional示例詳解

    Spring條件注解@Conditional示例詳解

    這篇文章主要給大家介紹了關(guān)于Spring條件注解@Conditional的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用Spring具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-08-08

最新評論

监利县| 天峻县| 株洲市| 英超| 微山县| 古田县| 定远县| 延边| 南岸区| 慈利县| 哈尔滨市| 湖北省| 贵溪市| 沙雅县| 西平县| 灵山县| 阿图什市| 烟台市| 泸水县| 东辽县| 亚东县| 广灵县| 衡阳县| 芜湖市| 柘荣县| 盐津县| 孟村| 迭部县| 策勒县| 凉山| 疏附县| 湾仔区| 马龙县| 石屏县| 荃湾区| 盐源县| 东兴市| 鄂托克旗| 山西省| 呼和浩特市| 洞口县|