@Condition 用法说明
满足条件的,才会被配置或构建。v2.1.4 后支持
属性 | 说明 |
---|---|
onClass | 有类(只能一个;其实没必要多个) |
onClassName | 有类名 |
onProperty | 有属性 |
onMissingBean | 没有 Bean |
onMissingBeanName | 没有 Bean Name |
onBean | 有 Bean。v2.9 后支持 |
onBeanName | 有 Bean Name。v2.9 后支持 |
关于“onClass”和“onClassName”:
- 检测类的本质其实是检查对应的依赖包是否引入了
- 同一个依赖包内的类,用一个即可;不同依赖包的类,建议分开检测
关于“onProperty”,有三种用法:
- "${yyy.enable}",有属性即可
- "${yyy.enable} = true",有属性且=true(只支持=号,简单才高效;复杂的手写)
- "${yyy.enable:true} = true",没属性(通过默认值加持)或者有属性且=true
1、加在 @Bean
函数上
@Bean
函数可以返回 null,有些复杂的条件可以在函数内处理。
@Configuration
public class DemoConfig{
//检查否类有类存在,然后再产生它的bean
@Bean
//@Condition(onClassName="org.aaa.IXxxAaaImpl") //有类名
@Condition(onClass=IXxxAaaImpl.class) //有类
public IXxx getXxx(){
return new IXxxAaaImpl();
}
//检查有配置存在,然后再产生对应的bean
@Bean
//@Condition(onProperty="${yyy.enable}") //有属性值
@Condition(onProperty="${yyy.enable} = true") //有属性值,且等于true
public IYyy getYyy(@Inject("${yyy.config}") IYyyImpl yyy){
return yyy;
}
}
2、加在组件类上(任何组件类)
使用 onClass 条件时,组件不能继承自检测类。不然获取类元信息时直接会异常
- 例
@Condition(onClass=XxxDemo.class)
@Configuration
public class DemoConfig{ //DemoConfig 不能扩展自 XxxDemo
}
@Condition(onClass=XxxDemo.class)
@Component
public class DemoCom{ //DemoCom 不能扩展自 XxxDemo
}
- 实例
@Condition(onClass = SaSsoManager.class)
@Configuration
public class SaSsoAutoConfigure {
@Bean
public SaSsoConfig getConfig(@Inject(value = "${sa-token.sso}", required = false) SaSsoConfig ssoConfig) {
return ssoConfig;
}
@Bean
public void setSaSsoConfig(@Inject(required = false) SaSsoConfig saSsoConfig) {
SaSsoManager.setConfig(saSsoConfig);
}
@Bean
public void setSaSsoTemplate(@Inject(required = false) SaSsoTemplate ssoTemplate) {
SaSsoUtil.ssoTemplate = ssoTemplate;
SaSsoProcessor.instance.ssoTemplate = ssoTemplate;
}
}
3、onMissingBean 条件与 List[Bean] 注入的边界
- onMissingBean 条件的执行时机为,Bean 扫描完成并检查之后才执行的
- List[Bean](或 Map[String, Bean]) 注入,也是在 Bean 扫描完成后尝试注入的。
@Configuration
public class TestConfig{
@Condition(onMissingBean = Xxx.class)
@Bean
public Xxx aaa(){
...
}
@Condition(onMissingBean = Yyy.class)
@Bean
public Yyy bbb(List<Xxx> xxxList ){
...
}
@Condition(onMissingBean = Zzz.class)
@Bean
public Zzz ccc(List<Yyy> yyyList ){
...
}
}
在 v2.8.0 之前,还有谁未完成注册?是不可知的(没有做依赖探测)。像上面的示例,xxxList 是好的,yyyList 可能会傻掉。xxxList 和 yyyList 是相同的注入时机(谁先谁后,无序),此时 Yyy 因为依赖 xxxList,所以并未生成。
以上注解方式,也可以采用手写方式处理:
@Component
public class TestConfig implements LifecycleBean {
@Inject
AppContext context;
@Override
public void start() throws Throwable {
if(!context.hasWrap(Xxx.class)){
context.wrapAndPut(Xxx.class, new Xxx());
}
if(!context.hasWrap(Yyy.class)){
List<Xxx> xxxList = context.getBeansOfType(Xxx.class);
context.wrapAndPut(Yyy.class, new Yyy(xxxList));
}
if(!context.hasWrap(Zzz.class)){
List<Yyy> yyyList = context.getBeansOfType(Yyy.class);
context.wrapAndPut(Zzz.class, new Zzz(yyyList));
}
}
}