@Conditional
Spring 提供了profile进行一个动态配置选择,同时更加细力度的,我们可以使用@Conditional来实现。可以说profile能够实现的,@Conditional都能够实现。
@Configuration
@Conditional({Main.MyCondition.class})
@Main.MyAnnotation({"123", "456"})
@Main.MyAnnotation1
public class Main {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(Main.class);
context.refresh();
}
@Bean
//@Conditional({Main.MyCondition.class}) 和@Profile一样,也可以用在Bean上
public MyBean myBean2() {
System.out.println("---- myBean2 init ----");
return new MyBean();
}
public static class MyBean {
}
public static class MyCondition implements Condition {
@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
System.out.println("ClassName --> " + context.getClass());
System.out.println("Registry --> " + context.getRegistry());
System.out.println("BeanFactory --> " + context.getBeanFactory());
System.out.println("Environment --> " + context.getEnvironment());
System.out.println("ClassLoader --> " + context.getClassLoader());
System.out.println(metadata.getAnnotationAttributes(MyAnnotation.class.getName()));
System.out.println(metadata.getAllAnnotationAttributes(MyAnnotation.class.getName()));
// return false; 如果返回false的话,就不会打印出myBean init
return true;
}
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyAnnotation {
String[] value();
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@MyAnnotation(value = {"111", "222"}, name = "333")
public @interface MyAnnotation1 {
}
}
要使用@Conditional功能,我们要自己定义一个规则,通过实现Condition接口的matches方法,如果返回true,那么就是条件成立,将会使用这个配置或者注册这个Bean;否则,反之。
接口中传入的ConditionContext可以获取当前Spring的一些全局变量,如BeanFactory和Registry等。AnnotatedTypeMetadata可以返回当前使用了这个注解的地方的所有注解信息,比如例子中的MyAnnotation。getAnnotationAttributes和getAllAnnotationAttributes的不同点是getAnnotationAttributes不能获取到注解的继承属性,但是getAllAnnotationAttributes可以。