在spring某些场景下,我们希望随着某些配置项/类的存在与否,决定一些bean是否被实例化并加载到spring容器。
@Conditional系列注解,便是这个问题的解决方案。
文章目录
- 相关注解罗列
- 1. @Conditional注解 (`spring context包下注解`)
- 2. @ConditionalOnProperty注解 (`spring boot包下注解`)
- 3. @ConditionalOnClass (`spring boot包下注解`)
- 4. @ConditionalOnBean (`spring boot包下注解`)
- 5. @ConditionalOnMissingClass (`spring boot包下注解`)
- 6. @ConditionalOnMissingBean (`spring boot包下注解`)
- 7. @ConditionalOnCloudPlatform (`spring boot包下注解`)
- 8. @ConditionalOnExpression (`spring boot包下注解`)
- 9. @ConditionalOnJava (`spring boot包下注解`)
- 10. @ConditionalOnNotWebApplication (`spring boot包下注解`)
- 11. @ConditionalOnWebApplication (`spring boot包下注解`)
- 12. @ConditionalOnWarDeployment (`spring boot包下注解`)
- 13. @ConditionalOnWarDeployment (`spring boot包下注解`)
- 14. @ConditionalOnResource (`spring boot包下注解`)
- 15. @ConditionalOnSingleCandidate (`spring boot包下注解`)
相关注解罗列
1. @Conditional注解 (spring context包下注解
)
需要给定一个value参数,value必须继承Condition接口,实现match方法。
举例:声明一个名为datasource的bean,我们希望只有在存在配置项 lele.datasource.enabled
并且为true时才加载该bean。
@Configuration
public class BeanConfig {
@Conditional({DataSourceCondition.class})
@Bean(name = "datasource")
public DataSource(){
return DataSource build = DataSourceBuilder.create()
.driverClassName("test")
.url("test")
.username("test")
.password("test")
.build();
}
}
public class DataSourceCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
//获取ioc使用的beanFactory
ConfigurableListableBeanFactory beanFactory = conditionContext.getBeanFactory();
ClassLoader classLoader = conditionContext.getClassLoader();
Environment environment = conditionContext.getEnvironment();
BeanDefinitionRegistry registry = conditionContext.getRegistry();
String property = environment.getProperty("lele.datasource.enabled");
if (property.equals(true)){
return true;
}
return false;
}
}
2. @ConditionalOnProperty注解 (spring boot包下注解
)
@ConditionalOnProperty 是springboot基于上述@Conditional注解实现的,他的功能单一但是使用上更加简单。
当存在指定配置项为指定value时,该bean才会被加载。
在 1 中的需求,这里只需要一行注解便可以实现。
@ConditionalOnProperty(name = "lele.datasource.enabled", havingValue = "true")
@Bean(name = "datasource")
public DataSource(){
return DataSource build = DataSourceBuilder.create()
.driverClassName("test")
.url("test")
.username("test")
.password("test")
.build();
}
注解主要参数解释
// 指定的配置项
String[] value() default {};
// 配置项等于这个值,才加载bean
String havingValue() default "";
// 如果没有配置项,是否生效/加载bean
boolean matchIfMissing() default false;
3. @ConditionalOnClass (spring boot包下注解
)
存在指定的class,才会加载该bean。其他同2
参数: Class<?>[] value() default {};
4. @ConditionalOnBean (spring boot包下注解
)
存在指定的bean,才会加载该bean。其他同2
注解主要参数解释
/**
* 需要作为条件的类的Class对象数组
*/
Class<?>[] value() default {};
/**
* 需要作为条件的类的Name,Class.getName()
*/
String[] type() default {};
/**
* (用指定注解修饰的bean)条件所需的注解类
*/
Class<? extends Annotation>[] annotation() default {};
/**
* spring容器中bean的名字
*/
String[] name() default {};
/**
* 搜索容器层级,当前容器,父容器
*/
SearchStrategy search() default SearchStrategy.ALL;
/**
* 可能在其泛型参数中包含指定bean类型的其他类
*/
Class<?>[] parameterizedContainer() default {};
5. @ConditionalOnMissingClass (spring boot包下注解
)
不存在指定的class,才会加载该bean。其他同2
参数: Class<?>[] value() default {};
6. @ConditionalOnMissingBean (spring boot包下注解
)
不存在指定的bean,才会加载该bean。其他同2
注解主要参数解释
/**
* 需要作为条件的类的Class对象数组
*/
Class<?>[] value() default {};
/**
* 需要作为条件的类的Name,Class.getName()
*/
String[] type() default {};
/**
是否有需要过滤掉的子类
*/
Class<?>[] ignored() default {};
/**
同上,Class.getName()
*/
String[] ignoredType() default {};
/**
* (用指定注解修饰的bean)条件所需的注解类
*/
Class<? extends Annotation>[] annotation() default {};
/**
* spring容器中bean的名字
*/
String[] name() default {};
/**
* 搜索容器层级,当前容器,父容器
*/
SearchStrategy search() default SearchStrategy.ALL;
/**
* 可能在其泛型参数中包含指定bean类型的其他类
*/
Class<?>[] parameterizedContainer() default {};
7. @ConditionalOnCloudPlatform (spring boot包下注解
)
是否配置了SAP/CLOUD_FOUNDRY/HEROKU/KUBERNETES/等云平台 其他同2
8. @ConditionalOnExpression (spring boot包下注解
)
可通过spring提供的spEL表达式灵活配置 其他同2
9. @ConditionalOnJava (spring boot包下注解
)
可通过javaVersion限制是否加载该bean 其他同2
注解主要参数解释
// 需要比较的java版本
JavaVersion value();
// 当前实际java版本如何与java比较,EQUAL_OR_NEWER代表更新才加载,OLDER_THAN代表版本更老才加载
Range range() default Range.EQUAL_OR_NEWER;
10. @ConditionalOnNotWebApplication (spring boot包下注解
)
当前不是web环境才加载 其他同2
11. @ConditionalOnWebApplication (spring boot包下注解
)
当前是web环境才加载 其他同2
12. @ConditionalOnWarDeployment (spring boot包下注解
)
当前是war包部署才加载 其他同2
13. @ConditionalOnWarDeployment (spring boot包下注解
)
当前是war包部署才加载 其他同2
14. @ConditionalOnResource (spring boot包下注解
)
String[] resources参数指定的静态资源文件存在,才加载 其他同2
15. @ConditionalOnSingleCandidate (spring boot包下注解
)
指定bean只有拥有唯一“候选bean”时,才加载 参数含义同ConditionalOnBean