SpringBoot根据条件自动装配Bean(基于Condition接口和Conditional注解)

    在 SpringBoot 中,我们经常可以看到很多以 Condition 开头的注解,例如:ConditionalOnBeanConditionalOnMissingBeanConditionalOnClassConditionalOnMissingClassConditionalOnJavaConditionalOnPropertyConditionalOnResource等等,如果看它们的源码的话,可以发现它们都使用了@Conditional注解,并且指定了一个或者多个XxxCondition.class,再看XxxCondition源码,发现它们都实现了 Condition 接口。
    Condition接口和Conditional注解是SpringBoot提供的实现按条件自动装配 Bean 的工具。

如何使用 Condition 接口和 Conditional 注解

  • Condition 接口源码如下,自定义条件时实现该接口
/**
 * 实现 Condition 的 matches 方法,在此方法中进行逻辑判断
 * 方法返回值:
         * true:装载此类到 Spring 容器中
         * false:不装载此类到 Spring 容器中
 */
public interface Condition {
    boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata);
}
  • Conditional 注解源码如下
    使用方式:
    在配置类(带有@SpringBootConfiguration或者@Configuration的类)上加此注解或者在有@Bean的方法上加此注解,并指定实现了Condition接口的Class对象,注意:如果指定多个Class对象,当且仅当所有Classmatches方法都返回true时,才会装载BeanSpring中。
    使用范例:
    @Conditional(GBKCondition.class)@Conditional({GBKCondition.class, UTF8Condition.class})
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {
    /**
     * value:Class 对象数组,当配置多个 Class 对象时,当且仅当所有条件都返回 true 时,相关的 Bean 才可以被装载到 Spring 容器中
     */
    Class<? extends Condition>[] value();
}

案例

    以系统字符集判断系统加载GBK还是UTF-8的类

// 面向接口编程思想:编码转换接口
public interface EncodingConvert {
}
// UTF8 编码
public class UTF8EncodingConvert implements EncodingConvert {
}
// GBK 编码
public class GBKEncodingConvert implements EncodingConvert {
}
// GBK 加载条件,实现 Condition 接口,获取程序运行时参数,判断是否是加载该 Bean
public class GBKCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        String encoding = System.getProperty("file.encoding");
        return null != encoding ? ("GBK".equals(encoding.toUpperCase())) : false;
    }
}
// UTF-8 加载条件
public class UTF8Condition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        String encoding = System.getProperty("file.encoding");
        return null != encoding ? ("UTF-8".equals(encoding.toUpperCase())) : false;
    }
}
// 编码配置类
@SpringBootConfiguration
// @Conditional(value = { UTF8Condition.class, GBKCondition.class })
public class EncodingConvertConfiguration {
    @Bean
    @Conditional(GBKCondition.class)
    public EncodingConvert gbkEncoding() {
        return new GBKEncodingConvert();
    }
    @Bean
    @Conditional(value = UTF8Condition.class)
    public EncodingConvert utf8Encoding() {
        return new UTF8EncodingConvert();
    }
}
// 启动类
@SpringBootApplication
public class App {
    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(App.class, args);
        System.out.println(context.getBeansOfType(EncodingConvert.class));
        context.close();
    }
}

测试结果
这里写图片描述
这里写图片描述

猜你喜欢

转载自blog.csdn.net/qq_30038111/article/details/80197394