@Conditional 是条件装配注解,它的作用是当装配bean时,首先要按照一定条件去判断,只有满足条件才会将bean注册到容器。
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
Class<? extends Condition>[] value();
}
注解中只有一个class类型的属性,这个 class 便是需要实现条件判断的类,这个类必须实现 Condition 接口的 matches 方法,该方法会返回一个boolean类型值,通过这个值来判断条件是否成立。
Condition 接口:
@FunctionalInterface
public interface Condition {
/**
* Determine if the condition matches.
* @param context the condition context
* @param metadata 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);
}
Conditional相关的其它注解:
注解名称 | 描述 |
@ConditionalOnBean | 在某个 bean 存在的时候 |
@ConditionalOnMissingBean | 在某个 bean 不存在的时候 |
@ConditionalOnClass | 当前 classPath 下可以找到某个 class 的时候 |
@ConditionalOnMissingClass | 当前 classPath 下无法找到某个 class 的时候 |
@ConditionalOnResource | 当前 classPath 下是否存在某个资源文件 |
@ConditionalOnProperty | 当前 JVM 是否包含某个属性值 |
@ConditionalOnWebApplication | 当前 Spring context 是否是 web 应用程序 |
SPI
条件装配除了通过@Conditional 相关注解声明,还可以使用 SPI 的方式声明。
在 META-INF/spring-autoconfigure-metadata.properties 配置以下内容:
com.test.TestConfig.ConditionalOnClass=com.test.TestClass
这样一来,只有 com.test.TestClass 类存在的情况,才会加载 com.test.TestConfig 配置类。
Spring 在通过 AutoConfigurationImportSelector 加载 spring.factories 配置之前,会先扫描 spring-autoconfigure-metadata.properties 文件,从而过滤掉不满足条件的配置类。