SpringBoot中的條件注解

文章目錄

  • 前言
  • 什么是條件注解
  • 核心原理
  • 常用條件注解詳解
    • 1. @ConditionalOnClass和@ConditionalOnMissingClass
    • 2. @ConditionalOnBean和@ConditionalOnMissingBean
    • 3. @ConditionalOnProperty
  • 應用場景:多數據源配置
  • 在SpringBoot自動配置中的核心作用
    • 自動配置的工作原理
    • 經典自動配置示例分析
  • 總結

前言

在SpringBoot開發中,我們經常會遇到這樣的場景:某些Bean只有在特定條件下才需要被創建,或者根據不同的環境加載不同的配置。SpringBoot的條件注解就是為了解決這類問題而設計的。

什么是條件注解

條件注解是SpringBoot提供的一套機制,允許我們根據特定條件來決定是否創建Bean、加載配置或執行某些邏輯。這些注解基于Spring 4.0引入的@Conditional注解,SpringBoot在此基礎上擴展了更多實用的條件注解。

核心原理

所有的條件注解都基于@Conditional注解,該注解需要指定一個Condition接口的實現類。Condition接口只有一個方法:

public interface Condition {boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
}

當Spring容器加載Bean時,會調用這個方法來判斷條件是否滿足。如果返回true,則創建Bean;如果返回false,則跳過。

常用條件注解詳解

1. @ConditionalOnClass和@ConditionalOnMissingClass

這兩個注解用于檢查類路徑中是否存在指定的類。

@Configuration
public class DatabaseConfig {// 當類路徑中存在DataSource類時才創建這個Bean@Bean@ConditionalOnClass(DataSource.class)public DataSource dataSource() {return new HikariDataSource();}// 當類路徑中不存在Redis相關類時才創建內存緩存@Bean@ConditionalOnMissingClass("org.springframework.data.redis.core.RedisTemplate")public CacheManager memoryCache() {return new ConcurrentMapCacheManager();}
}

2. @ConditionalOnBean和@ConditionalOnMissingBean

這兩個注解根據Spring容器中是否存在指定的Bean來決定是否創建。

@Configuration
public class ServiceConfig {// 當容器中存在UserRepository Bean時才創建UserService@Bean@ConditionalOnBean(UserRepository.class)public UserService userService(UserRepository userRepository) {return new UserServiceImpl(userRepository);}// 當容器中不存在CacheManager時才創建默認的@Bean@ConditionalOnMissingBean(CacheManager.class)public CacheManager defaultCacheManager() {return new NoOpCacheManager();}
}

3. @ConditionalOnProperty

根據配置屬性來決定是否創建Bean,這是最常用的條件注解之一。

@Configuration
public class FeatureConfig {// 當spring.feature.enabled=true時才啟用這個功能@Bean@ConditionalOnProperty(prefix = "spring.feature",name = "enabled",havingValue = "true",matchIfMissing = false // 默認false,即屬性不存在時不匹配)public FeatureService featureService() {return new FeatureServiceImpl();}
}

應用場景:多數據源配置

@Configuration
public class DataSourceConfig {@Primary@Bean@ConditionalOnProperty(name = "app.datasource.primary.enabled", havingValue = "true")public DataSource primaryDataSource() {return DataSourceBuilder.create().url("jdbc:mysql://localhost:3306/primary").build();}@Bean@ConditionalOnProperty(name = "app.datasource.secondary.enabled", havingValue = "true")public DataSource secondaryDataSource() {return DataSourceBuilder.create().url("jdbc:mysql://localhost:3306/secondary").build();}
}

在SpringBoot自動配置中的核心作用

SpringBoot的自動配置是其最核心的特性之一,而條件注解正是自動配置得以智能化的關鍵所在。讓我們深入了解條件注解在自動配置中是如何發揮作用的。

自動配置的工作原理

SpringBoot通過spring.factories文件定義了所有的自動配置類,啟動時會加載這些配置。但是,并不是所有的配置都應該被激活,這就需要條件注解來控制。

# META-INF/spring.factories示例
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration

經典自動配置示例分析

讓我們看看SpringBoot內置的一些自動配置是如何使用條件注解的:

  1. RedisAutoConfiguration
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(RedisOperations.class)  // Redis類存在時才配置
@EnableConfigurationProperties(RedisProperties.class)
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {@Bean@ConditionalOnMissingBean(name = "redisTemplate")  // 用戶沒有自定義時才創建@ConditionalOnSingleCandidate(RedisConnectionFactory.class)public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {RedisTemplate<Object, Object> template = new RedisTemplate<>();template.setConnectionFactory(redisConnectionFactory);return template;}@Bean@ConditionalOnMissingBean@ConditionalOnSingleCandidate(RedisConnectionFactory.class)public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory) {return new StringRedisTemplate(redisConnectionFactory);}
}
  1. DataSourceAutoConfiguration
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ DataSource.class, EmbeddedDatabaseType.class })
@ConditionalOnMissingBean(type = "javax.sql.DataSource")  // 沒有數據源時才自動配置
@EnableConfigurationProperties(DataSourceProperties.class)
@Import({ DataSourcePoolMetadataProvidersConfiguration.class,DataSourceInitializationConfiguration.class })
public class DataSourceAutoConfiguration {@Configuration(proxyBeanMethods = false)@Conditional(EmbeddedDatabaseCondition.class)  // 自定義條件判斷@ConditionalOnMissingBean({ DataSource.class, XADataSource.class })@Import(EmbeddedDataSourceConfiguration.class)protected static class EmbeddedDatabaseConfiguration {}@Configuration(proxyBeanMethods = false)@Conditional(PooledDataSourceCondition.class)@ConditionalOnMissingBean({ DataSource.class, XADataSource.class })@Import({ HikariConfiguration.class, TomcatConfiguration.class,DbcpConfiguration.class, OracleUcpConfiguration.class,GenericConfiguration.class, DataSourceJmxConfiguration.class })protected static class PooledDataSourceConfiguration {}
}

總結

SpringBoot的條件注解是一個非常強大的特性,它讓我們能夠構建更加靈活和智能的應用程序。通過合理使用這些注解,不僅能讓我們寫出更優雅的代碼,也能讓我們的應用在面對不同場景時表現得更加智能。希望這篇文章能幫助大家更好地理解和使用SpringBoot的條件注解。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/96474.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/96474.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/96474.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

LightGBM時序預測詳解:從原理到 PSO 參數優化

前言 在時間序列預測領域&#xff0c;集成學習方法一直占據重要地位。此前我們介紹了基于傳統集成思想的時序預測方法&#xff08;查看前文&#xff09;&#xff0c;而梯度提升樹&#xff08;GBDT&#xff09;作為集成學習的佼佼者&#xff0c;在時序預測中表現尤為突出。本文…

django生成遷移文件,執行生成到數據庫

當報錯時 重新拉取git&#xff0c;重新生成遷移文件&#xff0c;重新執行 1、生成遷移文件 python manage.py makemigrations 子應用2、執行建表、建字段、修改字段 python manage.py migrate 子應用3、當手動已經在數據庫創建字段時&#xff0c; 用 --fake 標記遷移為 “已應用…

2025軟件供應鏈安全技術路線未來趨勢預測

軟件供應鏈安全已從一個技術圈的議題演變為全球企業的治理焦點。近幾年&#xff0c;APT滲透、惡意包植入、開發者誤操作等不同類型的供應鏈安全事件頻發&#xff0c;使得“安全的代碼來源”和“可信的交付鏈路”成為企業數字化轉型的生命線。2025年的軟件供應鏈安全&#xff0c…

用戶登錄Token緩存Redis實踐:提升SpringBoot應用性能

前言在現代Web應用中&#xff0c;用戶認證和授權是至關重要的功能。傳統的基于數據庫的Token存儲方式雖然簡單易用&#xff0c;但在高并發場景下容易成為性能瓶頸。本文將介紹如何將SpringBoot項目中的用戶Token從數據庫存儲遷移到Redis緩存&#xff0c;顯著提升系統性能。一、…

深度解析Structured Outputs:讓AI輸出嚴格遵循JSON Schema的結構化響應

深度解析Structured Outputs&#xff1a;讓AI輸出嚴格遵循JSON Schema的結構化響應 引言 在現代應用開發中&#xff0c;JSON 是最流行的數據交換格式之一。為了提升 API 接口的健壯性和數據一致性&#xff0c;結構化輸出&#xff08;Structured Outputs&#xff09;成為了大模…

關于 微服務中服務注冊與發現 的詳細說明,涵蓋主流框架/解決方案的對比、核心功能、配置示例及總結表格

以下是關于 微服務中服務注冊與發現 的詳細說明&#xff0c;涵蓋主流框架/解決方案的對比、核心功能、配置示例及總結表格&#xff1a;1. 服務注冊與發現的核心概念 服務注冊與發現是微服務架構的基礎能力&#xff0c;主要解決以下問題&#xff1a; 服務注冊&#xff1a;服務實…

08高級語言邏輯結構到匯編語言之邏輯結構轉換 continue break 完結匯編按邏輯結構

目錄 &#x1f4da; 1. continue 語句的原理與實現 &#x1f6e0; 1.1 continue 語句的基本概念 ?? 1.2 底層原理 &#x1f4d6; 1.3 案例分析&#xff1a;跳過偶數&#xff0c;累加奇數 &#x1f680; 2. break 語句的原理與實現 &#x1f6e0; 2.1 break 語句的基本概…

AI出題人給出的Java后端面經(二十二)(日更)

鏈接雙端鏈表 前一篇&#xff1a;AI出題人給出的Java后端面經&#xff08;二十一&#xff09;&#xff08;日更&#xff09; 后一篇&#xff1a;null 目錄 &#x1f535; 一、Java基礎&#xff08;集合/流式/OOP&#xff09; 答案&#xff1a; 題目1&#xff1a;集合遍歷性…

AI賦能體育訓練突破:AI動作捕捉矯正精準、戰術分析系統提效率,運動員破瓶頸新路徑

傳統體育訓練長期受限于 “動作矯正依賴教練主觀判斷”“戰術分析滯后于賽場變化”“運動員體能分配憑經驗摸索” 的難題&#xff0c;而 AI 技術的深度介入&#xff0c;正讓體育訓練從 “經驗驅動” 轉向 “數據驅動”&#xff0c;既能實時捕捉動作偏差&#xff0c;又能動態優化…

【python實用小腳本-194】Python PNR一鍵查票:輸入號碼秒出座位狀態——再也不用刷12306

Python PNR一鍵查票&#xff1a;輸入號碼秒出座位狀態——再也不用刷12306 PNR查詢, 實時座位, 離線腳本, 零廣告, 瑞士軍刀 故事開場&#xff1a;一把瑞士軍刀救了趕火車的你 周五傍晚&#xff0c;你拎著行李沖向站臺&#xff0c;手機信號一格&#xff0c;12306 死活刷不出座位…

【python】python進階——推導式

目錄 一、推導式介紹 二、推導式的用法 2.1 列表推導式 2.2 字典推導式 2.3 集合推導式 2.4 生成器表達式 三、推導式的嵌套和復雜用法 3.1 嵌套推導式 3.2 多重條件推導式 四、推導式對比傳統循環 4.1 性能比較 4.2 可讀性比較 五、常見應用場景 5.1 數據清…

數字安全隱形基石:隨機數、熵源與DRBG核心解析與技術關聯

前言&#xff1a;數字安全的 “隱形基石” 在數字化浪潮席卷全球的今天&#xff0c;從金融交易的密鑰生成到區塊鏈的共識機制&#xff0c;從量子通信的加密協議到智能汽車的身份認證&#xff0c;隨機數如同空氣般滲透在信息系統的每一個安全節點。然而&#xff0c;看似簡單的 …

TDengine IDMP 最佳實踐

最佳實踐 IDMP 提供了一強大的數據建模能力&#xff0c;讓數據標準化、情景化&#xff0c;從而可以更好地利用 AI 技術&#xff0c;從數據中挖掘出業務價值&#xff0c;但數據建模本身是一個很難用 AI 完成的事情。 為最大程度減少建模的成本&#xff0c;TDengine 推薦在數據…

8.20網絡編程——sqlite3數據庫

文章目錄一、思維導圖二、學生管理系統1、myhead.h2、代碼三、牛客網刷題一、思維導圖 二、學生管理系統 1、myhead.h #ifndef __MYHEAD_H__ #define __MYHEAD_H__#include <string.h> #include <stdio.h> #include <stdlib.h> #include <errno.h>#d…

電腦不能訪問服務器磁盤,連不上服務器。解決辦法:在窗口中輸入 regedit 確定即可打開注冊表,。。。。0改為1,確認;

打開注冊表&#xff1a; 按鍵盤上的 WinR 鍵&#xff0c;打開運行窗口&#xff0c;在窗口中輸入 regedit 確定即可打開注冊表。&#xff08;或者直接在左下角搜索框中搜索“注冊表”&#xff09; 依次打開以下目錄 計算機\HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Service…

EP4CE40F23I7N Altera FPGA Cyclone IV E

EP4CE40F23I7N 阿爾特拉 Altera Cyclone IV E 系列的一顆中等密度、低功耗 FPGA&#xff0c;通信接口與工業控制等應用。該器件采用成熟的工藝制程&#xff0c;器件規模約為 39k 左右的邏輯單元&#xff08;Logic Elements&#xff09;&#xff0c;由若干邏輯陣列塊&#xff08…

【typenum】 21 類型級別計算最大公約數(Gcd)

一、源碼 代碼實現了一個在類型級別計算最大公約數&#xff08;GCD&#xff09;的系統 定義&#xff08;type_operators.rs&#xff09; /// A **type operator** that computes the [greatest common divisor][gcd] of Self and Rhs. /// /// [gcd]: https://en.wikipedia.org…

如何為 Visual Studio 2019 安裝 WDK

我用nmake編譯代碼提示錯誤&#xff1a;fatal error U1052: 未找到文件“\makefile.def”&#xff0c;經過排查發現是代碼依賴WDK&#xff0c;所以研究了一下WDK的安裝步驟&#xff0c;下面是具體步驟&#xff1a; 請遵循以下步驟來為你的 VS2019 搭建完整的驅動開發環境&…

使用 Apache Flink CDC 3.0 實現 MySQL 到 Elasticsearch 的數據同步

下面我將創建一個完整的 Spring Boot 項目&#xff0c;使用 Flink CDC 3.0 基于 MySQL 的 binlog 實現數據同步到 Elasticsearch。 項目概述 這個項目將&#xff1a; 使用 Flink CDC 連接 MySQL 并讀取 binlog處理數據變化&#xff08;插入、更新、刪除&#xff09;將數據同步到…

Web網站的運行原理2

請求Web網站的文件-HTTP 可以使用HTTP協議在Web瀏覽器和Web服務器應用程序之間傳輸Web網頁的文件。 在進行HTTP傳輸之前&#xff0c;需要先在Web瀏覽器和Web服務器應用程序之間建立TCP連接。 使用HTTP請求可以要求Web瀏覽器向Web服務器應用程序傳輸文件。 傳輸Web網站的文件-HT…