springboot @ConditionalOnMissingBean注解的作用详解

1,832 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第24天,点击查看活动详情

前言

  • 最近在搭建公司后台服务整合分布式,提供了一个底层公共支持模块,但是里面有些组件已经被大部分模块重新实现了,而我有不想让别人改动代码来兼容我的基建模块,突然想到springboot的Condition模块是否能够实现这个功能呢?

ConditionalOnMissingBean

  • 主要实现是当你的bean已经被注册了就不会在注册该配置所产生的的bean了,这样就能够很灵活的支持各种复杂的场景了。但是还是没有解决我的问题,我需要的是有A B 两个bean都被 primary注解标注了,我想要的是如果存在A 则B的失效,否则B生效。

  • @ConditionalOnMissingBean 它是修饰bean的一个注解,主要实现的是,当你的bean被注册之后,如果再注册相同类型的bean,就不会成功

  • 当你在做组件封装的时候经常需要考虑的是兼容性,实现功能的同时还需要考虑到扩展性,而扩展性就是功能不能限定死,必须能够方便使用者进行定制化,这时候 ConditionalOnMissingBean 完美

Condition

  • 上面提到的 ConditionalOnMissingBeanCondition 的一个实现类, Condition的主要作用就是用于判断是否满足注册bean的条件。
  • 除了系统提供的默认的条件判断类,我们还可以通过自定义的方式来进行实现。

public class TestCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {

        Environment env = context.getEnvironment();

        String property = env.getProperty("os.name");

        if (property.contains("Windows")){
            return true;
        }
        return false;
    }
}


  • 这样我们就可以在注册bean的时候通过@Conditional(TestCondition.class)来根据系统选择性是否注入bean了。

  • 另外我们有时候条件并不是单一的,我们往往是多个条件进行选择判断的,在Conditional 中是多个条件取交集的关系进行判断的。

ConditionalOnExpression

  • @ConditionalOnExpression是springboot提供的非常好用的注解。
    @ConditionalOnExpression("'true") 当括号中的内容为true时 ,使用该注解的类被实例化。

它可以和@Service、@Component、@Controller、@Repository 、@Bean 、@Configuration 等注解一起使用。可以通过SPEL 表达式、读取配置文件属性来让IOC容器选择性的扫描加入指定的某个Bean。而不是将所有实现类Bean都加入到IOC,这样会造成一定的资源浪费。简单来说就是按需加载,而不是全部加载

总结

  • 不要一味的实现功能,还需要考虑后续货站问题,这时候我们就需要使用可插拔模式进行功能开发,springboot帮我们实现的start脚本就是一个很好的例子。