话不多说,先上代码:
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来进行实现的,试想一下,如果我们选择好了配置了,如果能随意变动,那岂不是很尴尬。