@Conditional注解

 

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();
}