SpringBoot之条件注解
本文最后更新于 2025-11-06,文章内容可能已经过时。
SpringBoot的条件注解是实现"按需配置"的核心机制,它们允许开发者根据特定条件动态决定Bean的创建与配置的生效。所有条件注解都基于
@Conditional元注解构建,通过实现Condition接口的matches()方法进行条件判断。
一、基于类存在性的条件注解
1. @ConditionalOnClass
-
作用:当类路径上存在指定类时,条件成立
-
属性:
value:要检查的类的Class类型数组name:要检查的类或接口的全限定名(字符串形式)
-
典型使用场景:自动配置类中检查依赖库是否存在
-
示例:
@Configuration @ConditionalOnClass({DataSource.class, EntityManager.class}) public class JpaAutoConfiguration { // 当类路径存在DataSource和EntityManager时生效 }
2. @ConditionalOnMissingClass
-
作用:当类路径上不存在指定类时,条件成立
-
属性:
value(与@ConditionalOnClass的value作用相反) -
典型使用场景:当特定依赖不存在时才启用某个功能
-
示例:
@Configuration @ConditionalOnMissingClass("com.example.MyClass") public class MyAutoConfiguration { // 当类com.example.MyClass不存在时生效 }
二、基于Bean存在性的条件注解
3. @ConditionalOnBean
-
作用:当容器中存在指定Bean时,条件成立
-
属性:
value:指定匹配的Bean类型(Class数组)type:指定匹配的Bean类型全限定名name:指定匹配的Bean名称parameterizedContainer:检查泛型类型实现annotation:检查被特定注解标注的Beanmatch:匹配类型(默认MatchType.ALL,需全部存在;MatchType.ANY,存在一个即可)
-
典型使用场景:避免重复注册Bean,或为默认Bean提供自定义覆盖
-
示例:
@Bean @ConditionalOnBean(DataSource.class) public JdbcTemplate jdbcTemplate(DataSource dataSource) { return new JdbcTemplate(dataSource); }
4. @ConditionalOnMissingBean
-
作用:当容器中不存在指定Bean时,条件成立
-
属性:与
@ConditionalOnBean相同,但多了:ignored:匹配时要忽略的Class类型数组ignoredType:匹配时要忽略的Class类型数组名称
-
典型使用场景:提供默认Bean实现,允许用户通过自定义Bean覆盖
-
示例:
@Bean @ConditionalOnMissingBean(DataSource.class) public DataSource defaultDataSource() { return new HikariDataSource(); }
三、基于配置属性的条件注解
5. @ConditionalOnProperty
-
作用:根据配置文件(如application.yml)中的属性值决定是否生效
-
属性:
name:配置属性名havingValue:属性期望的值matchIfMissing:如果属性不存在,是否视为满足条件(默认false)
-
典型使用场景:功能开关、多环境配置切换
-
示例:
@Configuration @ConditionalOnProperty(name = "app.cache.enabled", havingValue = "true") public class CacheConfig { // 当app.cache.enabled=true时加载 }
四、基于Web环境的条件注解
6. @ConditionalOnWebApplication
-
作用:当应用是Web应用时生效
-
属性:
type(指定Web应用类型,如WebApplicationType.SERVLET) -
典型使用场景:Web应用特有的配置
-
示例:
@Configuration @ConditionalOnWebApplication(type = WebApplicationType.SERVLET) public class WebConfig { // 仅在Servlet Web应用中生效 }
7. @ConditionalOnNotWebApplication
-
作用:当应用不是Web应用时生效
-
典型使用场景:非Web应用特有的配置
-
示例:
@Configuration @ConditionalOnNotWebApplication public class NonWebConfig { // 仅在非Web应用中生效 }
五、基于资源存在性的条件注解
8. @ConditionalOnResource
-
作用:当指定资源存在时生效
-
属性:
resources(资源路径数组) -
典型使用场景:检查特定配置文件是否存在
-
示例:
@Configuration @ConditionalOnResource(resources = "classpath:application.properties") public class ResourceConfig { // 当application.properties存在时生效 }
六、基于Java版本的条件注解
9. @ConditionalOnJava
-
作用:根据Java版本决定是否生效
-
属性:
value(指定Java版本,如JavaVersion.EIGHT) -
典型使用场景:针对不同Java版本的特定实现
-
示例:
@Configuration @ConditionalOnJava(JavaVersion.EIGHT) public class Java8Config { // 仅在Java 8及以上版本生效 }
七、基于表达式的条件注解
10. @ConditionalOnExpression
-
作用:根据SpEL表达式决定是否生效
-
属性:
value(SpEL表达式字符串) -
典型使用场景:复杂条件判断
-
示例:
@Configuration @ConditionalOnExpression("${app.feature.enabled:false}") public class FeatureConfig { // 当配置属性app.feature.enabled为true时生效 }
八、其他条件注解
11. @ConditionalOnSingleCandidate
-
作用:当指定类型在容器中只有一个候选Bean时生效
-
属性:
value(Bean类型) -
典型使用场景:确保唯一Bean的配置
-
示例:
@Bean @ConditionalOnSingleCandidate(DataSource.class) public DataSource dataSource() { return new HikariDataSource(); }
九、条件注解的组合使用
条件注解可以组合使用,实现更复杂的条件判断:
@Configuration
@ConditionalOnClass(DataSource.class)
@ConditionalOnProperty(name = "app.database.enabled", havingValue = "true")
@ConditionalOnWebApplication
public class DatabaseConfig {
// 仅在Web应用、存在DataSource类、且app.database.enabled=true时生效
}
十、条件注解的实现原理
条件注解的核心原理是基于Spring的@Conditional元注解,它要求实现Condition接口的matches()方法:
public interface Condition {
boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
}
SpringBoot中的每个条件注解都对应一个Condition实现类,例如OnClassCondition用于@ConditionalOnClass,OnBeanCondition用于@ConditionalOnBean等。
总结
SpringBoot的条件注解体系非常丰富,覆盖了从类存在性、Bean存在性、配置属性、Web环境、资源存在性、Java版本到表达式判断的全方位条件判断场景。通过这些条件注解,SpringBoot实现了强大的"按需配置"能力,使得应用配置更加灵活、适应性更强,避免了不必要的资源消耗和潜在的冲突。
使用条件注解的最佳实践包括:明确条件判断逻辑、避免过度复杂的条件组合、合理使用@ConditionalOnMissingBean提供默认配置、在配置类上使用合适的条件注解等。
- 感谢你赐予我前进的力量

