目录

1. @Conditional 注解

2. Spring boot 扩展

1) @ConditionalOnClass和@ConditionalOnMissingClass注解

2) @ConditionalOnBean 和@ConditionalOnMissingBean注解

3) @ConditionalOnProperty注解


1. @Conditional 注解

@Conditional注解是Spring-context模块提供了一个注解,该注解的作用是可以根据一定的条件来使@Configuration注解标记的配置类是否生效,代码如下:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//package org.springframework.context.annotation;import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Conditional {Class<? extends Condition>[] value();
}

value值为实现Condition 接口的一个Class,Spring框架根据实现Conditon接口的matches方法返回true或者false来做以下操作,如果matches方法返回true,那么该配置类会被Spring扫描到容器里, 如果为false,那么Spring框架会自动跳过该配置类不进行扫描装配,使用方法:

实现Condition接口, 例如在配置文件里配置了dataSource.none=true, 那么表示不需要使用数据源,那么Spring在扫描的时候会自动跳过该配置类。

package com.bing.sh.datasource;import org.springframework.context.annotation.Condition;
import org.springframework.context.annotation.ConditionContext;
import org.springframework.core.type.AnnotatedTypeMetadata;/*** 如果为返回false,那么Spring会忽略配置类*/
public class DataSourceCondition implements Condition {@Overridepublic boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {// 此处使用 conditionContext获取Environment即可。String configureDataSource = conditionContext.getEnvironment().getProperty("dataSource.none", "false");return "false".equals(configureDataSource);}}

定义配置类,与@Conditional注解一起使用:

@Configuration
@Conditional(value = DataSourceCondition.class)
public class CustomDataSourceConfig {}

除了Conditional注解,Spring boot 框架提供了 其他conditional系列注解。

2. Spring boot 扩展

SpringBoot的spring-boot-autoconfigure模块也提供了Conditional系列的相关注解,这些注解能帮助开发者根据一定的条件去装载需要的Bean。

1) @ConditionalOnClass和@ConditionalOnMissingClass注解

当Spring加载的Bean被@ConditionOnClass注解标记时,类加载器会先去先找到指定的Class, 如果没有找到目标Class,那么被ConditionOnClass注解标记的类不会被Spring装载,相反ConditionalOnMissingBean是指如果没有找到目标Class, 那么就装载该类。

2) @ConditionalOnBean 和@ConditionalOnMissingBean注解

当Spring加载的Bean被@ConditionalOnBean注解标记时,接下来会先找到指定的Bean,如果没有找到目标Bean,那么被@ConditionalOnBean标记的类不会被Spring装载,相反ConditionalOnMissingBean是指如果没有Class, 那么就装载该Bean。

看一个例子, Dubbo与Springboot做自动装配时,先寻找BASE_PACKAGES_BEAN_NAME这个Bean, 如果Bean 不存在,那么serviceAnnotationBeanProcessor这个Bean不会被Spring 装载.

@ConditionalOnProperty(prefix = DUBBO_PREFIX, name = "enabled", matchIfMissing = true)
@Configuration
@AutoConfigureAfter(DubboRelaxedBindingAutoConfiguration.class)
@EnableConfigurationProperties(DubboConfigurationProperties.class)
@EnableDubboConfig
public class DubboAutoConfiguration {/*** Creates {@link ServiceAnnotationPostProcessor} Bean* dubbo.scan.base-packages* @param packagesToScan the packages to scan* @return {@link ServiceAnnotationPostProcessor}*/@ConditionalOnProperty(prefix = DUBBO_SCAN_PREFIX, name = BASE_PACKAGES_PROPERTY_NAME)// 先找BASE_PACKAGES_BEAN_NAME 这个bean, 如果没有这个bean, 那么serviceAnnotationBeanProcessor不会被Spring装载。@ConditionalOnBean(name = BASE_PACKAGES_BEAN_NAME)@Beanpublic ServiceAnnotationPostProcessor serviceAnnotationBeanProcessor(@Qualifier(BASE_PACKAGES_BEAN_NAME)Set<String> packagesToScan) {return new ServiceAnnotationPostProcessor(packagesToScan);}}

使用@ConditionalOnMissingBean注解定义BASE_PACKAGES_BEAN_NAME这个Bean

/*** Dubbo Relaxed Binding Auto-{@link Configuration} for Spring Boot 2.0** @see DubboRelaxedBindingAutoConfiguration* @since 2.7.0*/
@Configuration
@ConditionalOnProperty(prefix = DUBBO_PREFIX, name = "enabled", matchIfMissing = true)
@ConditionalOnClass(name = "org.springframework.boot.context.properties.bind.Binder")
@AutoConfigureBefore(DubboRelaxedBindingAutoConfiguration.class)
public class DubboRelaxedBinding2AutoConfiguration {public PropertyResolver dubboScanBasePackagesPropertyResolver(ConfigurableEnvironment environment) {ConfigurableEnvironment propertyResolver = new AbstractEnvironment() {@Overrideprotected void customizePropertySources(MutablePropertySources propertySources) {Map<String, Object> dubboScanProperties = getSubProperties(environment.getPropertySources(), DUBBO_SCAN_PREFIX);propertySources.addLast(new MapPropertySource("dubboScanProperties", dubboScanProperties));}};ConfigurationPropertySources.attach(propertyResolver);return propertyResolver;}/*** The bean is used to scan the packages of Dubbo Service classes* 如果没有就创建* @param environment {@link Environment} instance* @return non-null {@link Set}* @since 2.7.8*/@ConditionalOnMissingBean(name = BASE_PACKAGES_BEAN_NAME)@Bean(name = BASE_PACKAGES_BEAN_NAME)public Set<String> dubboBasePackages(ConfigurableEnvironment environment) {PropertyResolver propertyResolver = dubboScanBasePackagesPropertyResolver(environment);return propertyResolver.getProperty(BASE_PACKAGES_PROPERTY_NAME, Set.class, emptySet());}@ConditionalOnMissingBean(name = RELAXED_DUBBO_CONFIG_BINDER_BEAN_NAME, value = ConfigurationBeanBinder.class)@Bean(RELAXED_DUBBO_CONFIG_BINDER_BEAN_NAME)@Scope(scopeName = SCOPE_PROTOTYPE)public ConfigurationBeanBinder relaxedDubboConfigBinder() {return new BinderDubboConfigBinder();}}

3) @ConditionalOnProperty注解

该注解的作用是解析application.yml/application.properties 里的配置生成条件来生效,也是与@Configuration注解一起使用。

属性

功能

其他

prefix

读取配置里的前缀值为prefix的属性, 如果没有返回false

name

读取属性配置里的Key值,如果配置了prefix,那么需要先拼接prefix然后匹配havingValue值

havingValue

匹配属性里的值

matchIfMissing

当未找到对应的配置时是否匹配,默认为false, 如果为true,没有找到配置,那么也匹配。

使用场景,例如在指定数据源时,指定datasource的type。例如包含如下配置使用Hikari数据源。

spring.datasource.type=com.zaxxer.hikari.HikariDataSource

在使用时,一般设置matchIfMissing=false, 这样条件没有匹配上的话会Spring在扫描bean时会自动跳过该配置类。

也可以设定matchIfMissing=true,这种场景例如缓存,我们可以这样配置默认是开启缓存的。

@ConditionalOnProperty(name={cache.effect},marchIfMissing=true)public class CacheAutoConfiguration{// ...}

如果在application.properties里配置cache.effect=false, 那么该配置类就会跳过,这样配置就能使缓存不生效。

详解Spring Boot框架中的@Conditional系列注解相关推荐

  1. 详解 | Spring Boot 最核心的 3 个注解详解

    Hi !我是小小,开始本周的第一篇,本周第一篇内容是关于Spring Boot 最核心的三个注解,将会对这三个注解进行详细解释. 前言 Spring Boot 最大的特点是无需 XML 配置文件,能够 ...

  2. Spring Boot框架中使用Jackson的处理总结

    1.前言 通常我们在使用Spring Boot框架时,如果没有特别指定接口的序列化类型,则会使用Spring Boot框架默认集成的Jackson框架进行处理,通过Jackson框架将服务端响应的数据 ...

  3. springboot 扫描jar包中bean_详解Spring Boot的Component Scan原理

    本文将帮助您了解Spring中最重要的概念 - 组件扫描.Spring Boot在组件扫描方面做了一些魔术 @ComponentScan 如果你了解组件扫描,你就会理解Spring.Spring是一个 ...

  4. 万字长文:详解 Spring Boot 中操作 ElasticSearch

    点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 作者 | 超级小豆丁 来源 | http://www.m ...

  5. elasticsearch 客户端工具_万字长文:详解 Spring Boot 中操作 ElasticSearch

    点击上方"小强的进阶之路",选择"星标"公众号 优质文章,及时送达 预计阅读时间: 15分钟 一.ElasticSearch 简介 1.简介 ElasticSe ...

  6. java中的controller_详解Spring Boot中Controller用法

    Controller Controller是SpringBoot里最基本的组件,他的作用是把用户提交来的请求通过对URL的匹配,分配个不同的接收器,再进行处理,然后向用户返回结果.他的重点就在于如何从 ...

  7. springboot初始化逻辑_详解Spring Boot中初始化资源的几种方式

    假设有这么一个需求,要求在项目启动过程中,完成线程池的初始化,加密证书加载等功能,你会怎么做?如果没想好答案,请接着往下看.今天介绍几种在Spring Boot中进行资源初始化的方式,帮助大家解决和回 ...

  8. springboot 集成redis_一文详解Spring Boot 集成 Redis

    redis设置: 修改redis服务器的配置文件 vim /usr/local/redis/bin/redis.confbind 0.0.0.0 protected-mode no 重新启动redis ...

  9. 详解Spring Boot 2.X使用缓存@Cacheable代码示例

    从3.1开始,Spring引入了对Cache的支持.其使用方法和原理都类似于Spring对事务管理的支持.Spring Cache是作用在方法上的,其核心思想是这样的:当我们在调用一个缓存方法时会把该 ...

最新文章

  1. 微调torchvision 0.3的目标检测模型
  2. java中native的用法[转]
  3. bootstrap基础学习十一篇
  4. Dijkstra模板
  5. mysql binlog 回退_MYSQL Binglog分析利器:binlog2sql使用详解
  6. java 调用python脚本过程_通过Java调用Python脚本
  7. 小师妹学JVM之:JIT中的LogCompilation
  8. c#字符串操作自我总结
  9. Flink 1.9 实战:使用 SQL 读取 Kafka 并写入 MySQL
  10. 绕开登录进行爬虫_爬虫小偏方:绕开登陆和访问频率控制
  11. MySQL笔记(八)存储过程procedure
  12. 前端开发~uni-app ·[项目-仿糗事百科] 学习笔记 ·005【设置全局属性globalStyle】
  13. 操作系统_图解deepin操作系统安装,体验定制版的国产操作系统
  14. 28. HTTP、SSL/TLS和HTTPS协议的区别与联系
  15. 解决办法:对BZ2_bzDecompressInit/BZ2_bzDecompress/BZ2_bzDecompressEnd未定义的引用
  16. gp3688写频线制作_摩托罗拉GP3688对讲机写频软件(摩托罗拉对讲机写频工具) 官方版...
  17. 偏最小二乘法(PLS)Python代码
  18. ros::Rate loop_rate(10); loop_rate.sleep(); 在程序中是休眠到一定时间,并不占用CPU时间
  19. 【爬虫——00004】蜘蛛技能学习
  20. 弘辽科技:拼多多商品限制推广多久解封?怎么申诉?

热门文章

  1. 瑞萨电子基于RISC-V的电机控制ASSP解决方案
  2. 美国FBI招工试题,七个经典心理题
  3. 应用软件和操作系统的本质区别
  4. java笔试面试题及答案(华为篇)
  5. hackthebox-sauna (域渗透/bloodhound使用/mimikatz使用/secretsdump.py、psexec使用)
  6. 程序员来聊一聊信用卡(四)——哪些银行的哪些卡容易办、值得办
  7. Superblock
  8. 文件系统:inode、entry、superblock
  9. jsp网上图书销售管理系统ssh论文
  10. PYNQ_Z2自定义IP核