前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringBoot-Bean条件注入

SpringBoot-Bean条件注入

作者头像
OPice
发布2019-11-04 02:41:54
8730
发布2019-11-04 02:41:54
举报
文章被收录于专栏:D·技术专栏D·技术专栏

  之前有篇文章Springboot 排除不想加载的配置只是排除,如果有些复杂场景需要根据条件来判断 就需要Spring 支持的另外一种方式 ——@Conditional注解。

借此来看下Spring对于条件注入的支持

@Conditional

定义Condition

代码语言:javascript
复制
public class MetaqCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        String property = context.getEnvironment().getProperty("ons.type");
        return "metaq".equalsIgnoreCase(property);
    }
}
public class MqCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        String property = context.getEnvironment().getProperty("ons.type");
        return "mq".equalsIgnoreCase(property);
    }
}

java config

代码语言:javascript
复制
@Configuration
@Slf4j
public class ConditionalAutoConfig {

    @Bean
    @Conditional(MqCondition.class)
    public Consumer mqConsumerCondition() {
        Properties properties = new Properties();
        properties.put("AccessKey", "accessKey");
        properties.put("SecretKey", "secretKey");
        properties.put("ONSAddr", "http://onsaddr-internet.aliyun.com/rocketmq/nsaddr4client-internet");
        properties.put("ConsumerId", "iotConsumerId");
        Consumer consumer = ONSFactory.createConsumer(properties);
        log.info("create mq consumer");
        return consumer;
    }

    @Bean
    @Conditional(MetaqCondition.class)
    public MetaPushConsumer metaPushConsumer() {
        MetaPushConsumer consumer = new MetaPushConsumer("consumerId");
        log.info("create metaq consumer");
        return consumer;
    }
}

配置文件

ons.type=mq 启动项目 log输出 create mq consumer

Conditional 如何解析 看下AnnotatedBeanDefinitionReader.doRegisterBean()

代码语言:javascript
复制
<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
            @Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
        //将配置类信息转成AnnotatedGenericBeanDefinition 
        AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
        //@Conditional装配条件判断是否跳过注册
        if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
            return;
        }
······

扩展

  • @ConditionalOnBean:当容器中有指定Bean的条件下。
  • @ConditionalOnClass:当classpath类路径下有指定类的条件下。
  • @ConditionalOnCloudPlatform:当指定的云平台处于active状态时。
  • @ConditionalOnExpression:基于SpEL表达式的条件判断。
  • @ConditionalOnJava:基于JVM版本作为判断条件。
  • @ConditionalOnJndi:在JNDI存在的条件下查找指定的位置。
  • @ConditionalOnMissingBean:当容器里没有指定Bean的条件。
  • @ConditionalOnMissingClass:当类路径下没有指定类的条件下。
  • @ConditionalOnNotWebApplication:当项目不是一个Web项目的条件下。
  • @ConditionalOnProperty:当指定的属性有指定的值的条件下。
  • @ConditionalOnResource:类路径是否有指定的值。
  • @ConditionalOnSingleCandidate:当指定的Bean在容器中只有一个,或者有多个但是指定了首选的Bean。
  • @ConditionalOnWebApplication:当项目是一个Web项目的条件下

案例

  • @ConditionalOnProperty
代码语言:javascript
复制
1、@ConditionalOnProperty(prefix = "ons",name = "type",havingValue = "mq")

配置ons.type=mq 生效

代码语言:javascript
复制
2、@ConditionalOnProperty(prefix = "ons",name = {"type","env"},havingValue = "mq")

配置ons.type=mq 同时ons.env=mq 缺一不可才会生效

代码语言:javascript
复制
3、@ConditionalOnProperty(prefix = "ons",name ="type",havingValue = "mq", matchIfMissing=true)

配置 没有也会生效 matchIfMissing=true

  • @ConditionalOnExpression
代码语言:javascript
复制
1、@ConditionalOnExpression("${ons.type:true}")

配置ons.type=true时生效

代码语言:javascript
复制
2、@ConditionalOnExpression("'${ons.type}'".equals('mq'))

配置ons.type=mq时生效

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • @Conditional
    • 定义Condition
      • java config
        • 配置文件
        • 扩展
        • 案例
        相关产品与服务
        容器服务
        腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档