首發位址:Spring條件注解@Conditional,SpringBoot中組合條件你知道嗎?
導讀:當我們建構一個 Spring 應用的時候,有時我們想在滿足指定條件的時候才将某個 bean 加載到應用上下文中, Spring 4提供了一個更通用的基于條件的Bean的建立方式,即使用@Conditional注解,我們可以通過 @Conditional 注解來實作這類操作。
@Conditional 元注解源碼
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIwIjNx8CX39CXy8CXycXZpZVZnFWbp9DciV2du8me4lmNmBnav52LcRzNwUTOzUzLcVmdhNXLwRHdo9CXt92YucWbpRWdvx2Yx5yazF2Lc9CX6MHc0RHaiojIsJye.webp)
Conditional 接口源碼
我們看到 @Conditional 注解接收的參數是 extends Condition 接口的泛型類,也就是說,我們要使用 @Conditional 注解,隻需要實作 Condition 接口并重寫其方法即可:
簡單找下Spring家族其他的案例實作SpringBootCondition
Spring Boot使用的所有Condition實作的基礎。提供合理的日志記錄,以幫助使用者診斷要加載的類。
無意中在網上看到一種比較形象的了解:如果将Application Context 比作大廳,Spring Boot 在 @Conditional 注解的基礎上進行了細化,無需出示複雜的介紹信 (實作 Condition 接口),隻需要手持預定義好的 @ConditionalOnXxxx 注解印章的門票,如果驗證通過,就會走進 Application Context 大廳
SpringBoot Condition 拓展實作
逐個打開這 13 個注解,我們發現這些注解上有相同的元注解
從這些标記上我們可以了解如下内容:
- 都可以應用在 TYPE 上,也就是說,Spring 自動掃描的一切類 (@Configuration, @Component, @Service, @Repository, or @Controller) 都可以通過添加相應的 @ConditionalOnXxxx 來判斷是否加載
- 都可以應用在 METHOD 上,是以有 @Bean 标記的方法也可以應用這些注解
- 都是用了 @Conditional 注解來标記,OnBeanCondition 等自定義 Condition 還是實作了 Condition 接口的,換湯不換藥,沒什麼神秘的,隻不過做了更具象的封裝罷了,來看類依賴圖(簡化的類圖)
其實用法都大同小異,看了源碼以後發現原理很簡單,這裡簡單歸納下用法:
除了自己自定義Condition之外,Spring還提供了很多Condition給我們用
-
@ConditionalOnBean
僅僅在目前上下文中存在某個對象時,才會執行個體化一個Bean
-
@ConditionalOnClass
某個class位于類路徑上,才會執行個體化一個Bean
-
@ConditionalOnExpression
當表達式為true的時候,才會執行個體化一個Bean
-
@ConditionalOnMissingBean
僅僅在目前上下文中不存在某個對象時,才會執行個體化一個Bean
-
@ConditionalOnMissingClass
某個class類路徑上不存在的時候,才會執行個體化一個Bean
-
@ConditionalOnNotWebApplication
不是web應用
-
@ConditionalOnProperty
指在配置裡配置的屬性是否為true,才會執行個體化一個Bean)
-
@ConditionalOnResource
如果我們要加載的 bean 依賴指定資源是否存在于 classpath 中,那麼我們就可以使用這個注解
-
@ConditionalOnJndi
隻有指定的資源通過 JNDI 加載後才加載 bean
-
@ConditionalOnCloudPlatform
隻有運作在指定的雲平台上才加載指定的 bean,CloudPlatform 是 org.springframework.boot.cloud 下一個 enum 類型的類,大家可以打開自行看看
到這裡,你已經了解了如何靈活配置 bean,希望大家打開 IDE,自行檢視這些注解,了解更多具體内容。(共勉:多看源碼,學習大神的代碼設計)