package org.springframework.context.annotation;
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
/**
* All {@link Condition} classes that must {@linkplain Condition#matches match}
* in order for the component to be registered.
*/
Class<? extends Condition>[] value();
}
package org.springframework.context.annotation;
@FunctionalInterface
public interface Condition {
/**
* Determine if the condition matches.
* @param context the condition context
* @param metadata the metadata of the {@link org.springframework.core.type.AnnotationMetadata class}
* or {@link org.springframework.core.type.MethodMetadata method} being checked
* @return {@code true} if the condition matches and the component can be registered,
* or {@code false} to veto the annotated component's registration
*/
boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
}
1. 基本概念
@Conditional 是一个元注解(meta-annotation),可以被其他自定义注解使用。它的作用是根据指定的条件判断是否应该将某个 Bean 或配置类注册到 Spring 容器中。
使用场景:
根据环境变量、系统属性或运行时条件加载不同的 Bean。
实现多环境配置(如开发、测试、生产环境)。
动态切换功能模块。
2. 核心原理
@Conditional 的工作原理是通过实现 Condition 接口来定义条件逻辑。Spring 在解析带有 @Conditional 注解的 Bean 或配置类时,会调用 Condition 接口的 matches 方法,根据返回值决定是否注册该 Bean。
3. 内置条件注解
Spring 提供了一些常用的基于 @Conditional 的注解,可以直接使用:
(1)@ConditionalOnClass
作用:只有当指定的类存在于类路径中时,才会加载 Bean。
@Bean
@ConditionalOnClass(name = "com.example.SomeLibraryClass")
public SomeBean someBean() {
return new SomeBean();
}
(2)@ConditionalOnMissingClass
作用:只有当指定的类不存在于类路径中时,才会加载 Bean。
@Bean
@ConditionalOnMissingClass("com.example.SomeLibraryClass")
public SomeBean someBean() {
return new SomeBean();
}
(3)@ConditionalOnProperty
作用:根据配置文件中的属性值决定是否加载 Bean。
参数:
name
:属性名。
havingValue
:期望的属性值。
matchIfMissing
:如果属性不存在时是否匹配。
@Bean
@ConditionalOnProperty(name = "feature.enabled", havingValue = "true")
public FeatureBean featureBean() {
return new FeatureBean();
}
(4)@ConditionalOnBean
作用:只有当容器中存在指定类型的 Bean 时,才会加载当前 Bean。
@Bean
@ConditionalOnBean(SomeOtherBean.class)
public SomeBean someBean() {
return new SomeBean();
}
(5)@ConditionalOnMissingBean
作用:只有当容器中不存在指定类型的 Bean 时,才会加载当前 Bean。
@Bean
@ConditionalOnMissingBean
public SomeBean someBean() {
return new SomeBean();
}
(6)@ConditionalOnExpression
作用:基于 SpEL 表达式的结果决定是否加载 Bean。
@Bean
@ConditionalOnExpression("${feature.enabled} == true")
public SomeBean someBean() {
return new SomeBean();
}