Spring提供了很多Condition给我们用,@ConditionalOnSingleCandidate表示当指定Bean在容器中只有一个,或者虽然有多个但是指定首选Bean,这个组合了@Conditional元注解,只是使用了不同的条件(Conditional)
详细参考:
@Conditional,满足特定条件创建一个Bean,SpringBoot就是利用这个特性进行自动配置的。
例子:
首先,两个Condition,判断当前系统是否是Windows或者Linux(True False)
public class LinuxCondition implements Condition {
@Override
public boolean matches(ConditionContext arg0, AnnotatedTypeMetadata arg1) {
return arg0.getEnvironment().getProperty("os.name").contains("Linux");
}
}
public class WindowsCondition implements Condition {
@Override
public boolean matches(ConditionContext arg0, AnnotatedTypeMetadata arg1) {
return arg0.getEnvironment().getProperty("os.name").contains("Windows");
}
}
然后,2个ListService实现类,表明不同系统下的ListService实现。
public interface ListService {
public String showListCmd();
}
public class LinuxListService implements ListService{
@Override
public String showListCmd() {
return "ls";
}
}
public class WindowsListService implements ListService{
@Override
public String showListCmd() {
return "dir";
}
}
然后ConditionConfig使用了Java配置与@Conditional注解,根据LinuxCondition,或者WindowsCondition作为判断条件
@Configuration
public class ConditionConfig {
@Bean
@Conditional(WindowsCondition.class)
public ListService windowsListService() {
return new WindowsListService();
}
@Bean
@Conditional(LinuxCondition.class)
public ListService linuxListService() {
return new LinuxListService();
}
}
最后,App.java 测试成功。
public class App {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(
ConditionConfig.class);
ListService ls = context.getBean(ListService.class);
System.out.println(context.getEnvironment().getProperty("os.name")
+ "系统下的列表命令为:" + ls.showListCmd());
}
}