通过活动的profile,我们可以获得不同的Bean。Spring 4提供了一个更通用的基于条件的Bean的创建方式,即使用@Conditional注解。
@Conditional根据满足某个特定的条件创建一个特定的Bean。比如,当某一个jar包在一个类路径下时,自动配置一个或者多个Bean。或者只有一个Bean创建时,才会创建另一个Bean。总的来说,就是根据特定条件来控制Bean的创建行为,这样我们可以利用这个特征进行一些自动配置。Springboot中将会大量应用到条件注解。
下面的示例将以不同的操作系统作为条件,通过实现Condition接口,并重写其matches方法来构造判断条件。如在windows下运行程序输出dir,Linux下输出ls。
1、定义判断条件
(1)判定windows的条件
public class WindowsCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
return conditionContext.getEnvironment().getProperty("os.name").contains("Windows");
}
}
(2)判定linux的条件
public class LinuxCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
return conditionContext.getEnvironment().getProperty("os.name").contains("Linux");
}
}
2、不同系统的Bean类
(1)接口
public interface ListService {
public String showListCmd();
}
(2)Windows下所要创建的Bean的类
public class WindowsListService implements ListService {
@Override
public String showListCmd() {
return "dir";
}
}
(3)Linux下所要创建的Bean的类
public class LinuxListService implements ListService {
@Override
public String showListCmd() {
return "ls";
}
}
3、配置类
@Configuration
public class ConditionConfig {
@Bean
@Conditional(WindowsCondition.class)
public ListService windowsListService(){
return new WindowsListService();
}
@Bean
@Conditional(LinuxCondition.class) //通过@Conditional注解,符合Linux条件则实例化LinuxListService
public ListService linuxListService(){
return new LinuxListService();
}
}
4、运行
public class Main {
public static void main(String[] args){
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(ConditionConfig.class);
ListService listService = context.getBean(ListService.class);
System.out.println(context.getEnvironment().getProperty("os.name") +"系统下的列表命令为:"+listService.showListCmd());
}
}
运行结果为:
Windows 7系统下的列表命令为:dir
除了自己自定义Condition之外,Spring还提供了很多Condition给我们用
@ConditionalOnBean(仅仅在当前上下文中存在某个对象时,才会实例化一个Bean)
@ConditionalOnClass(某个class位于类路径上,才会实例化一个Bean)
@ConditionalOnExpression(当表达式为true的时候,才会实例化一个Bean)
@ConditionalOnMissingBean(仅仅在当前上下文中不存在某个对象时,才会实例化一个Bean)
@ConditionalOnMissingClass(某个class类路径上不存在的时候,才会实例化一个Bean)
@ConditionalOnNotWebApplication(不是web应用)