Spring boot 的 Conditional注解 用来判断是否应该注册指定的组件,Conditional需要与Condition接口配合使用。使用方式是在配置类或者方法上添加如下注解,如果满足
XxxCondition的matches条件则注册该组件。
@Conditional(XxxCondition.class)
Conditional注解有一个属性,Condition类型的Class数组,Condition有一个matches方法,返回布尔值,如果返回true,则注册该组件。
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
Class extends Condition>[] value();
}
@FunctionalInterface
public interface Condition {
boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
}
判断当前环境配置中condition.enable的值,如果为true则注册User
public class User{
@Override
public String toString() {
return "user";
}
}
public class MyOnPropertyCondition implements Condition {
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
String enable = conditionContext.getEnvironment().getProperty("condition.enable");
return "true".equals(enable);
}
}
在application.properties中添加配置
condition.enable=true
然后配置User,并注解 @Conditional(MyOnPropertyCondition.class),启动应用。可以看到程序输出结果为:user
@SpringBootApplication
public class Application implements CommandLineRunner {
@Bean
@Conditional(MyOnPropertyCondition.class)
public User user (){
return new User();
}
@Autowired(required = false)
private User user;
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
@Override
public void run(String... args) throws Exception {
System.out.println(user);
}
}
将application.properties中配置改为false,再次启动应用,可以看到输出结果为:null,也就是User并没有被注册到spring容器中
condition.enable=false
Spring Boot 中有很多Condition实现,他们都继承自 SpringBootCondition这个抽象基类。SpringBootCondition 实现了matches方法,并抽象出getMatchOutcome方法用于子类继承。
public abstract class SpringBootCondition implements Condition {
private final Log logger = LogFactory.getLog(getClass());
@Override
public final boolean matches(ConditionContext context,
AnnotatedTypeMetadata metadata) {
String classOrMethodName = getClassOrMethodName(metadata);
ConditionOutcome outcome = getMatchOutcome(context, metadata);
logOutcome(classOrMethodName, outcome);
recordEvaluation(context, classOrMethodName, outcome);
return outcome.isMatch();
}
...
public abstract ConditionOutcome getMatchOutcome(ConditionContext context,
AnnotatedTypeMetadata metadata);
...
}
上边的简单样例中,根据属性值来判断是否注册组件,在spring boot中的实现是:
class OnPropertyCondition extends SpringBootCondition {
...
}
我们使用的时候只需要在配置类或者方法中注解@ConditionalOnProperty就可以了。
@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD })
@Documented
@Conditional(OnPropertyCondition.class)
public @interface ConditionalOnProperty {
...
}
spring boot 提供了很多Condition如下: