Spring @Conditional使用指南

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/ksdb0468473/article/details/72961423

话不多说,先上代码:

public interface YRZTClient {

    YRZTClient getYRZTClient();

    String getUser();

    String getPassword();

}

这里是接口,我们在调用代码的时候,调用的是这个接口,具体怎么实现这个接口,我们还需要两个实现类:

public class Channel1YRZTClient implements YRZTClient {

    private String user = "channel1111111user";

    private String password = "channel1111111111password";

    @Override
    public String getUser() {
        return user;
    }

    @Override
    public String getPassword() {
        return password;
    }

    @Override
    public YRZTClient getYRZTClient() {
        return new Channel1YRZTClient();
    }
}
public class Channel2YRZTClient implements YRZTClient {

    private String user = "channel222222user";

    private String password = "channel222222222password";

    @Override
    public String getUser() {
        return user;
    }

    @Override
    public String getPassword() {
        return password;
    }

    @Override
    public YRZTClient getYRZTClient() {
        return new Channel2YRZTClient();
    }
}

那这两个实现类要如何选择呢?下面就需要@Conditional注解了:

@Configuration
public class YRZTConditionConfig {

    @Bean
    @Type(1)
    @Conditional(Channel1YRZTCondition.class)
    public YRZTClient channel1YRZTClient() {
        return new Channel1YRZTClient();
    }

    @Bean
    @Type(2)
    @Conditional(Channel2YRZTCondition.class)
    public YRZTClient channel2YRZTClient() {
        return new Channel2YRZTClient();
    }

}

先定义一个配置类,这个配置类配置了这两个实现类,但是这两个实现类并不是都实现的,而是通过@Conditional(Channel1YRZTCondition.class)和@Conditional(Channel2YRZTCondition.class)来进行判断,那么这两个类是如何实现的呢?

public class Channel1YRZTCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        Template template = context.getBeanFactory().getBean(Template.class);
        MultiValueMap<String, Object> allAnnotationAttributes = metadata.getAllAnnotationAttributes(Type.class.getName());
        boolean annotated = metadata.isAnnotated(Type.class.getName());
        return true;
    }
}
public class Channel2YRZTCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        return false;
    }
}

上面的代码并没有具体的写,因为也没想到什么很好的例子,这里可以获取到已经注入的bean,也可以获取到在@Conditional上的其他的注解,也可以获取其他的系统环境变量等等信息,在具体用的时候可以根据实际需要来进行判断即可,判断之后返回的值必须是布尔值的,代表了这个类是否可以注入。

还有一点值得注意:这个方法不能用于动态的在代码中来进行选择,比如我们常见的if else判断之类的,因为这个注解是在服务启动,spring注入bean的时候就已经注入好了的,没法动态的进行判断,一旦生效基本就是这个实现类了,不能随意切换,其实看一下源码就知道了,@Profile注解就是基于@Conditional来进行实现的,试想一下,如果我们选择好了配置了,如果能随意变动,那岂不是很尴尬。

猜你喜欢

转载自blog.csdn.net/ksdb0468473/article/details/72961423