你好,我是猿java
点击关注公众号👇,获取:大厂简历指导和加技术群深度讨论!
在 Spring 框架中,@Conditional
注解是什么?它有什么用途?它是如何工作的?这篇文章,我们来聊一聊。@Conditional
注解。
1. 什么是 @Conditional
?
首先,我们看看@Conditional
注解的源码,截图如下:

通过源码可以知道:@Conditional
是一个标记注解,表示组件只有全部匹配才有资格注册,它可以用于类和方法级别。更具体地说,@Conditional
允许开发者基于特定条件来决定是否加载某个 Bean或配置。它通过实现 Condition
接口的类来定义条件逻辑。当 Spring 容器在启动时解析 @Conditional
注解时,会调用对应的 Condition
实现来判断是否满足加载 Bean 或配置的条件。
2. 工作原理
关于 @Conditional
的工作原理,我们可以分为三个步骤来理解:
注解使用:在一个配置类、方法或者 Bean 上使用 @Conditional
注解,并指定一个或多个Condition
实现类。条件判断:当 Spring 容器加载配置时,会实例化并调用指定的 Condition
类的matches
方法。决定加载:根据 matches
方法的返回值(true
或false
),决定是否加载被注解的 Bean 或配置。
为了更好地理解 @Conditional
的工作原理,我们下面将通过代码示例来展示该注解常见地用法。
3. 常见用法
Spring 提供了多种基于不同条件的 Condition
实现,下面我们将从四个方面来讨论。
3.1 基于操作系统的条件
可以根据操作系统类型(如 Windows、Linux、macOS)来加载不同的 Bean。示例代码如下:
@Configuration
@ConditionalOnOperatingSystem(OS.WINDOWS)
public class WindowsConfig {
// Windows 专属 Bean 定义
}
@Configuration
@ConditionalOnOperatingSystem(OS.MAC)
public class WindowsConfig {
// MAC 专属 Bean 定义
}
实现示例:
Spring 提供了内置的 @ConditionalOnProperty
、@ConditionalOnClass
等注解,但基于操作系统的条件通常需自定义 Condition
。
3.2 基于类存在的条件
只有当特定的类在类路径中存在时,才会加载相关 Bean。这在模块化和插件化开发中尤为有用。
@Configuration
@ConditionalOnClass(name = "com.example.SomeClass")
public class SomeClassConfig {
// 当 com.example.SomeClass 存在时加载的 Bean
}
Spring 提供了 @ConditionalOnClass
注解,简化了这一需求。
3.3 基于属性的条件
可以根据配置文件中的属性值来决定是否加载某个 Bean。这在根据不同环境(开发、测试、生产)配置不同 Bean 时非常有用。
@Configuration
@ConditionalOnProperty(name = "feature.enabled", havingValue = "true")
public class FeatureConfig {
// 当 feature.enabled=true 时加载的 Bean
}
Spring 提供了 @ConditionalOnProperty
注解,方便基于属性进行条件化配置。
3.4 自定义条件
尽管 Spring 提供了许多内置的条件注解,但是,有些业务需求可能需要更复杂的条件逻辑。这时,我们可以创建自定义的 Condition
类。具体步骤如下:
实现 Condition
接口:
public class MyCustomCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
// 自定义条件判断逻辑
// 可以基于环境变量、配置文件、类路径等
return true; // 或 false
}
}
使用 @Conditional
注解:
@Configuration
@Conditional(MyCustomCondition.class)
public class MyCustomConfig {
// 配置 Bean
}
下面通过一个完整地例子来演示自定义条件的使用:假设我们希望只有在环境变量 MY_ENV
设置为 production
时加载某个 Bean。
public class ProductionEnvironmentCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
String env = context.getEnvironment().getProperty("MY_ENV", "development");
return"production".equalsIgnoreCase(env);
}
}
@Configuration
@Conditional(ProductionEnvironmentCondition.class)
public class ProductionConfig {
@Bean
public SomeService someService() {
returnnew ProductionSomeService();
}
}
在上述例子中,只有当 MY_ENV=production
时,ProductionSomeService
会被加载。
3.5 @Conditional
系列注解
除了上面的条件之外,Spring Boot 在 spring-boot-autoconfigure
模块中,扩展了 @Conditional
注解,提供了一系列更具体的条件注解,简化了常见的条件判断。这些注解通常以 @ConditionalOn
开头,如:
@ConditionalOnClass
:当指定类存在于类路径中时生效。@ConditionalOnMissingClass
:当指定类不存在于类路径中时生效。@ConditionalOnBean
:当指定的 Bean 存在时生效。@ConditionalOnMissingBean
:当指定的 Bean 不存在时生效。@ConditionalOnProperty
:当指定的属性满足条件时生效。@ConditionalOnResource
:当指定的资源存在时生效。@ConditionalOnWebApplication
:仅在 Web 应用环境中生效。@ConditionalOnNotWebApplication
:仅在非 Web 应用环境中生效。
4. 注意事项
上面,我们完整了分析了 @Conditional
注解,在使用该注解时,我们同时需要关注一些注意事项,这里总结了四点:
条件优先级:多个条件注解叠加时,它们的逻辑关系是“与”(AND)。即所有条件都满足,配置才会生效。 作用范围: @Conditional
可以用于类级别、方法级别或属性级别。不同的应用场景可能需要不同的使用方式。性能考虑:复杂的条件实现可能影响应用启动时间,尤其是在启动时需要进行大量逻辑判断的情况下。 可读性和维护性:过多或过于复杂的条件逻辑可能导致配置难以理解和维护。建议在必要时使用,并保持条件逻辑的清晰和简单。
5. 总结
本文,我们全面分析了@Conditional
注解的原理以及如何使用它,在 Spring生态系统中,@Conditional
注解扮演着至关重要的角色,因此,作为一个Java程序员,要想更深层次的理解 Spring,强烈建议掌握该注解。




