6.条件注解

84 阅读1分钟

条件注解:可以定义在不同的条件,当条件满足的时候,这个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());
    }
}

image.png

此时我们就可以添加条件注解

先添加一个类:

image.png

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);
    }
}

image.png