Spring 及 Spring Boot 條件化注解完整列表及示例
1. 所有條件化注解列表
Spring 和 Spring Boot 提供了以下條件化注解(共 15 個),用于在配置類或方法上實現條件化注冊 Bean 或配置:
注解名稱 | 作用 | 來源框架 |
---|---|---|
@Conditional | 自定義條件邏輯。 | Spring Core |
@ConditionalOnClass | 類路徑存在指定類時觸發。 | Spring Core |
@ConditionalOnMissingClass | 類路徑不存在指定類時觸發。 | Spring Core |
@ConditionalOnBean | 指定 Bean 存在時觸發。 | Spring Core |
@ConditionalOnMissingBean | 指定 Bean 不存在時觸發。 | Spring Core |
@ConditionalOnExpression | SpEL 表達式為 true 時觸發。 | Spring Core |
@ConditionalOnJava | 當前 Java 版本滿足條件時觸發。 | Spring Core |
@ConditionalOnProperty | 配置屬性存在且符合指定值時觸發。 | Spring Core |
@ConditionalOnResource | 類路徑存在指定資源文件時觸發。 | Spring Boot |
@ConditionalOnWebApplication | 當應用是 Web 應用時觸發。 | Spring Boot |
@ConditionalOnNotWebApplication | 當應用不是 Web 應用時觸發。 | Spring Boot |
@ConditionalOnSingleCandidate | 指定類型只有一個候選 Bean 或類型匹配時觸發。 | Spring Boot |
@ConditionalOnJndi | JNDI 資源存在時觸發。 | Spring Boot |
@ConditionalOnMissingJndi | JNDI 資源不存在時觸發。 | Spring Boot |
@ConditionalOnCloudPlatform | 當運行在指定云平臺(如 AWS、Azure)時觸發。 | Spring Cloud |
2. 完整代碼示例
(1) @Conditional
(自定義條件)
作用:通過實現 Condition
接口自定義條件邏輯。
// 自定義條件類
public class CustomCondition implements Condition {@Overridepublic boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {return context.getEnvironment().containsProperty("custom.key");}
}// 配置類
@Configuration
@Conditional(CustomCondition.class) // 自定義條件
public class CustomConditionConfig {@Beanpublic String customConditionBean() {return "Bean created by custom condition";}
}// 測試類
@SpringBootTest(properties = "custom.key=true")
class CustomConditionTest {@Autowired(required = false)private String customConditionBean;@Testvoid testWithCustomKey() {assertNotNull(customConditionBean);}
}
(2) @ConditionalOnClass
作用:類路徑存在指定類時觸發。
@Configuration
@ConditionalOnClass(DataSource.class) // 當存在 DataSource 類時觸發
public class ClassConditionConfig {@Beanpublic String dataSourceBean() {return "DataSource exists";}
}
(3) @ConditionalOnMissingClass
作用:類路徑不存在指定類時觸發。
@Configuration
@ConditionalOnMissingClass("org.springframework.jdbc.datasource.DataSource") // 當無 DataSource 類時觸發
public class MissingClassConditionConfig {@Beanpublic String noDataSourceBean() {return "DataSource does NOT exist";}
}
(4) @ConditionalOnBean
作用:指定 Bean 存在時觸發。
@Configuration
@ConditionalOnBean(name = "dataSource") // 當存在 dataSource Bean 時觸發
public class BeanConditionConfig {@Beanpublic String dataSourceDependentBean() {return "Bean created because dataSource exists";}
}
(5) @ConditionalOnMissingBean
作用:指定 Bean 不存在時觸發。
@Configuration
public class MissingBeanConditionConfig {@Bean@ConditionalOnMissingBean(name = "myBean") // 當無 myBean 時觸發public String missingBean() {return "Bean created because 'myBean' is missing";}
}
(6) @ConditionalOnExpression
作用:SpEL 表達式為 true
時觸發。
@Configuration
@ConditionalOnExpression("${app.env} == 'prod'") // 當 env 為 prod 時觸發
public class ExpressionConditionConfig {@Beanpublic String prodBean() {return "Bean for prod environment";}
}
(7) @ConditionalOnJava
作用:Java 版本滿足條件時觸發。
@Configuration
@ConditionalOnJava(baseline = JavaVersion.EIGHT, fallback = JavaVersion.TEN) // Java 8-10 時觸發
public class JavaVersionConditionConfig {@Beanpublic String java8To10Bean() {return "Java 8-10 compatible";}
}
(8) @ConditionalOnProperty
作用:配置屬性存在且符合指定值時觸發。
@Configuration
@ConditionalOnProperty(name = "feature.enabled", havingValue = "true") // 當 feature.enabled 為 true 時觸發
public class PropertyConditionConfig {@Beanpublic String enabledFeatureBean() {return "Feature enabled";}
}
(9) @ConditionalOnResource
作用:類路徑存在指定資源文件時觸發(Spring Boot)。
@Configuration
@ConditionalOnResource(resources = "classpath:config/application-prod.properties") // 當資源存在時觸發
public class ResourceConditionConfig {@Beanpublic String prodResourceBean() {return "Resource exists";}
}
(10) @ConditionalOnWebApplication
作用:應用是 Web 應用時觸發(Spring Boot)。
@Configuration
@ConditionalOnWebApplication // Web 應用時觸發
public class WebConditionConfig {@Beanpublic String webBean() {return "Web application";}
}
(11) @ConditionalOnNotWebApplication
作用:應用不是 Web 應用時觸發(Spring Boot)。
@Configuration
@ConditionalOnNotWebApplication // 非 Web 應用時觸發
public class NonWebConditionConfig {@Beanpublic String nonWebBean() {return "Non-web application";}
}
(12) @ConditionalOnSingleCandidate
作用:指定類型只有一個候選 Bean 時觸發(Spring Boot)。
@Configuration
@ConditionalOnSingleCandidate(DataSource.class) // 當唯一 DataSource 存在時觸發
public class SingleCandidateConditionConfig {@Beanpublic String singleDataSourceBean() {return "Single DataSource candidate";}
}
(13) @ConditionalOnJndi
作用:JNDI 資源存在時觸發(Spring Boot)。
@Configuration
@ConditionalOnJndi("java:comp/env/jdbc/MyDB") // 當 JNDI 資源存在時觸發
public class JndiConditionConfig {@Beanpublic String jndiBean() {return "JNDI resource exists";}
}
(14) @ConditionalOnMissingJndi
作用:JNDI 資源不存在時觸發(Spring Boot)。
@Configuration
@ConditionalOnMissingJndi("java:comp/env/jdbc/MyDB") // 當 JNDI 資源不存在時觸發
public class MissingJndiConditionConfig {@Beanpublic String noJndiBean() {return "JNDI resource does NOT exist";}
}
(15) @ConditionalOnCloudPlatform
作用:運行在指定云平臺時觸發(Spring Cloud)。
@Configuration
@ConditionalOnCloudPlatform(Azure.class) // 當運行在 Azure 時觸發
public class CloudConditionConfig {@Beanpublic String azureBean() {return "Bean for Azure environment";}
}
3. 條件注解對比表
注解 | 觸發條件 | 典型場景 | 參數示例 | 來源框架 |
---|---|---|---|---|
@Conditional | 自定義 Condition 接口實現的邏輯。 | 靈活的自定義條件。 | @Conditional(CustomCondition.class) | Spring Core |
@ConditionalOnClass | 類路徑存在指定類。 | 檢測依賴是否存在。 | @ConditionalOnClass(DataSource.class) | Spring Core |
@ConditionalOnMissingClass | 類路徑不存在指定類。 | 檢測依賴缺失。 | @ConditionalOnMissingClass("DataSource") | Spring Core |
@ConditionalOnBean | 指定 Bean 存在。 | 依賴其他 Bean 的存在。 | @ConditionalOnBean(name = "dataSource") | Spring Core |
@ConditionalOnMissingBean | 指定 Bean 不存在。 | 避免重復注冊 Bean。 | @ConditionalOnMissingBean(name = "myBean") | Spring Core |
@ConditionalOnExpression | SpEL 表達式為 true 。 | 復雜條件判斷。 | @ConditionalOnExpression("${app.env} == 'prod'") | Spring Core |
@ConditionalOnJava | 當前 Java 版本滿足條件。 | 根據 Java 版本啟用功能。 | @ConditionalOnJava(baseline = JavaVersion.EIGHT) | Spring Core |
@ConditionalOnProperty | 配置屬性存在且符合指定值。 | 根據配置啟用功能。 | @ConditionalOnProperty(name = "feature.enabled", havingValue = "true") | Spring Core |
@ConditionalOnResource | 類路徑存在指定資源文件。 | 根據資源文件存在與否配置。 | @ConditionalOnResource("classpath:config/prod.properties") | Spring Boot |
@ConditionalOnWebApplication | 應用是 Web 應用。 | Web 相關配置。 | @ConditionalOnWebApplication | Spring Boot |
@ConditionalOnNotWebApplication | 應用不是 Web 應用。 | 非 Web 應用配置。 | @ConditionalOnNotWebApplication | Spring Boot |
@ConditionalOnSingleCandidate | 指定類型只有一個候選 Bean 或類型匹配。 | 確保唯一 Bean。 | @ConditionalOnSingleCandidate(DataSource.class) | Spring Boot |
@ConditionalOnJndi | JNDI 資源存在。 | 根據 JNDI 資源觸發配置。 | @ConditionalOnJndi("java:comp/env/jdbc/MyDB") | Spring Boot |
@ConditionalOnMissingJndi | JNDI 資源不存在。 | 根據 JNDI 缺失觸發配置。 | @ConditionalOnMissingJndi("java:comp/env/jdbc/MyDB") | Spring Boot |
@ConditionalOnCloudPlatform | 運行在指定云平臺(如 AWS、Azure)。 | 云平臺相關配置。 | @ConditionalOnCloudPlatform(Azure.class) | Spring Cloud |
4. 總結
Spring 及 Spring Boot 的條件化注解通過 條件判斷 實現配置的動態加載,核心是 Condition
接口和其衍生注解。關鍵點如下:
- 依賴檢測:
@ConditionalOnClass
、@ConditionalOnMissingClass
、@ConditionalOnJndi
。 - Bean 狀態:
@ConditionalOnBean
、@ConditionalOnMissingBean
、@ConditionalOnSingleCandidate
。 - 屬性/環境:
@ConditionalOnProperty
、@ConditionalOnExpression
、@ConditionalOnJava
。 - 應用類型:
@ConditionalOnWebApplication
、@ConditionalOnNotWebApplication
。 - 云平臺:
@ConditionalOnCloudPlatform
(Spring Cloud)。 - 自定義條件:通過
@Conditional
實現靈活擴展。
這些注解幫助開發者根據運行時環境、依賴、配置等條件動態注冊 Bean,減少硬編碼,提升代碼的靈活性和可維護性。例如:
- Spring Boot 的
@ConditionalOnResource
可用于根據配置文件是否存在來啟用功能。 @ConditionalOnCloudPlatform
可在不同云平臺(如 AWS、Azure)間切換配置。@ConditionalOnJndi
適用于需要 JNDI 資源的環境(如企業級應用服務器)。
根據具體需求選擇合適的注解,可顯著簡化配置邏輯并增強代碼的適應性。