天天看點

Spring條件注解@Conditional,SpringBoot中組合條件你知道嗎?

首發位址:Spring條件注解@Conditional,SpringBoot中組合條件你知道嗎?

導讀:當我們建構一個 Spring 應用的時候,有時我們想在滿足指定條件的時候才将某個 bean 加載到應用上下文中, Spring 4提供了一個更通用的基于條件的Bean的建立方式,即使用@Conditional注解,我們可以通過 @Conditional 注解來實作這類操作。

@Conditional 元注解源碼

Spring條件注解@Conditional,SpringBoot中組合條件你知道嗎?
Spring條件注解@Conditional,SpringBoot中組合條件你知道嗎?

Conditional 接口源碼

我們看到 @Conditional 注解接收的參數是 extends Condition 接口的泛型類,也就是說,我們要使用 @Conditional 注解,隻需要實作 Condition 接口并重寫其方法即可:

Spring條件注解@Conditional,SpringBoot中組合條件你知道嗎?
Spring條件注解@Conditional,SpringBoot中組合條件你知道嗎?

簡單找下Spring家族其他的案例實作SpringBootCondition

Spring條件注解@Conditional,SpringBoot中組合條件你知道嗎?
Spring條件注解@Conditional,SpringBoot中組合條件你知道嗎?
Spring Boot使用的所有Condition實作的基礎。提供合理的日志記錄,以幫助使用者診斷要加載的類。

無意中在網上看到一種比較形象的了解:如果将Application Context 比作大廳,Spring Boot 在 @Conditional 注解的基礎上進行了細化,無需出示複雜的介紹信 (實作 Condition 接口),隻需要手持預定義好的 @ConditionalOnXxxx 注解印章的門票,如果驗證通過,就會走進 Application Context 大廳

SpringBoot Condition 拓展實作

Spring條件注解@Conditional,SpringBoot中組合條件你知道嗎?

逐個打開這 13 個注解,我們發現這些注解上有相同的元注解

從這些标記上我們可以了解如下内容:

  • 都可以應用在 TYPE 上,也就是說,Spring 自動掃描的一切類 (@Configuration, @Component, @Service, @Repository, or @Controller) 都可以通過添加相應的 @ConditionalOnXxxx 來判斷是否加載
  • 都可以應用在 METHOD 上,是以有 @Bean 标記的方法也可以應用這些注解
  • 都是用了 @Conditional 注解來标記,OnBeanCondition 等自定義 Condition 還是實作了 Condition 接口的,換湯不換藥,沒什麼神秘的,隻不過做了更具象的封裝罷了,來看類依賴圖(簡化的類圖)
Spring條件注解@Conditional,SpringBoot中組合條件你知道嗎?

其實用法都大同小異,看了源碼以後發現原理很簡單,這裡簡單歸納下用法:

除了自己自定義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,自行檢視這些注解,了解更多具體内容。(共勉:多看源碼,學習大神的代碼設計)