最本质的需求是根据条件加载Bean。 Spring4 提供了实现方案 — @Conditional ,可以通过条件判断创建 Bean 。
示例:
代码语言:javascript复制// java config
@Configuration
public class TestBeanConfig {
// 根据条件创建, 条件写在TestConditional类里
@Bean
@Conditional(TestConditional.class)
public TestBean createTestBean() {
return new TestBean();
}
}
// 配套的条件类实现
public class TestConditional implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
return false;
}
}
只有当 TestConditional.matches() 结果为 true 时才会创建 TestBean 。
注解 @Conditional
代码语言:javascript复制@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface Conditional {
Class[] value();
}
作用范围: 类,方法 包含参数: value, 接口Condition的实现类数组。数组内所有的条件都要满足哟!
参数 ConditionContext
代码语言:javascript复制public interface ConditionContext {
// 检查Bean定义
BeanDefinitionRegistry getRegistry();
// 检查Bean是否存在,甚至探查Bean的属性
ConfigurableListableBeanFactory getBeanFactory();
// 检查环境变量是否存在以及它的值是什么
Environment getEnvironment();
// 检查加载的资源
ResourceLoader getResourceLoader();
// 加载并检查类是否存在
ClassLoader getClassLoader();
}
参数 AnnotatedTypeMetadata
代码语言:javascript复制public interface AnnotatedTypeMetadata {
boolean isAnnotated(String annotationName);
Map<String, Object> getAnnotationAttributes(String annotationName);
Map<String, Object> getAnnotationAttributes(String annotationName, boolean classValuesAsString);
MultiValueMap<String, Object> getAllAnnotationAttributes(String annotationName);
MultiValueMap<String, Object> getAllAnnotationAttributes(String annotationName, boolean classValuesAsString);
}
- 借助 isAnnotated() 能够判断带有 @Bean 注解的方法是不是还有其他特定注解;
- 借助其他方法可以检查 @Bean 注解的方法上其他注解的属性;
附录
Spring Boot 在 @Conditional 基础上扩展了几个注解方便做此类判断:@ConditionalOnClass, @ConditionalOnMissingClass , @ConditionalOnBean , @ConditionalOnMissingBean ;