条件注解:可以定义在不同的条件,当条件满足的时候,这个Bean 才会被注册到Spring容器中
举例: 写一个接口,让两个类来实现它
public interface ShowCmd {
/**
* 这个接口返回文件列表的命令
* 如果Windows,那么返回dir
* 如果Linux,那么返回ls
* @return
*/
String show();
}
两个对应的实现类:
public class WindowsShowCmd implements ShowCmd{
@Override
public String show() {
return "dir";
}
}
public class LinuxShowCmd implements ShowCmd{
@Override
public String show() {
return "ls";
}
}
如果没有条件,那么启动容器时,这两个对象 都会被注册到容器中
@Configuration
public class JavaConfig {
@Bean
ShowCmd winCmd(){
return new WindowsShowCmd();
}
@Bean
ShowCmd linuxCmd(){
return new LinuxShowCmd();
}
}
那么,在像容器模糊的索要对象的时候(接口),就会报错:
public class Demo {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(JavaConfig.class);
ShowCmd showCmd = ctx.getBean(ShowCmd.class);
System.out.println("showCmd.show() = " + showCmd.show());
}
}
此时我们就可以添加条件注解
先添加一个类:
public class LinuxCondition implements Condition {
/**
* 通过返回true 和 false 来表示条件是否满足
* @param context
* @param metadata
* @return
*/
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
//获取当前操作系统的名字
String osName = context.getEnvironment().getProperty("os.name");
return osName.toLowerCase().contains("Linux");
}
}
给对应的Bean 添加@Conditional 注解
@Configuration
public class JavaConfig {
//表示 WindowsCondition 返回 ture ,这个bean 才会被注册到Spring 容器
@Bean
@Conditional(WindowsCondition.class)
ShowCmd winCmd(){
return new WindowsShowCmd();
}
//表示 LinuxCondition 返回 ture ,这个bean 才会被注册到Spring 容器
@Bean
@Conditional(LinuxCondition.class)
ShowCmd linuxCmd(){
return new LinuxShowCmd();
}
}
经典的条件注解案例:
@Bean
@Profile("prod")
DataSource prodDs(){
return new DataSource("url","prod");
}
@Bean
@Profile("prod")
DataSource devDs(){
return new DataSource("url","dev");
}
public class Demo {
public static void main(String[] args) {
// AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(JavaConfig.class);
// ShowCmd showCmd = ctx.getBean(ShowCmd.class);
// System.out.println("showCmd.show() = " + showCmd.show());
//如果直接传入启动类,这么容器就直接初始化了,Bean 也都初始化了
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.getEnvironment().addActiveProfile("pro");
ctx.register(JavaConfig.class);
ctx.refresh();
DataSource ds = ctx.getBean(DataSource.class);
System.out.println("ds = " + ds);
}
}