Spring Boot中@ConditionalOnProperty使用详解

摘要:
通过在ConditionalOnProperty上注释@Conditional代码,我们可以看到ConditionalOnProperty属于@Conditional的派生注释。有效条件由OnPropertyCondition判断。用法我们在上面的SpringBoot中看到了@ConditionalOnProperty的用法。ConditionalOnProperty的核心功能是通过属性名和havingValue实现的。但是,如果查看HttpEncodingAutoConfiguration类的属性配置,就会发现上面提到的名称和havingValue没有一起使用。

在Spring Boot的自动配置中经常看到@ConditionalOnProperty注解的使用,本篇文章带大家来了解一下该注解的功能。

Spring Boot中的使用

在Spring Boot的源码中,比如涉及到Http编码的自动配置、数据源类型的自动配置等大量的使用到了@ConditionalOnProperty的注解。

HttpEncodingAutoConfiguration类中部分源代码:

@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(HttpProperties.class)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@ConditionalOnClass(CharacterEncodingFilter.class)
@ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true)
public class HttpEncodingAutoConfiguration {
    // 省略内部代码
}

DataSourceConfiguration类中部分代码:

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(org.apache.tomcat.jdbc.pool.DataSource.class)
@ConditionalOnMissingBean(DataSource.class)
@ConditionalOnProperty(name = "spring.datasource.type", havingValue = "org.apache.tomcat.jdbc.pool.DataSource",
		matchIfMissing = true)
static class Tomcat {
  // 省略内部代码
}

很显然,以上两个自动配置类中都通过@ConditionalOnProperty来控制自动配置是否生效,下面我们来了解一下它的源码和具体使用。

@ConditionalOnProperty源码说明

@ConditionalOnProperty注解类源码如下:

@Retention(RetentionPolicy.RUNTIME)
@Target({ ElementType.TYPE, ElementType.METHOD })
@Documented
@Conditional(OnPropertyCondition.class)
public @interface ConditionalOnProperty {

	// 数组,获取对应property名称的值,与name不可同时使用
	String[] value() default {};

	// 配置属性名称的前缀,比如spring.http.encoding
	String prefix() default "";

	// 数组,配置属性完整名称或部分名称
	// 可与prefix组合使用,组成完整的配置属性名称,与value不可同时使用
	String[] name() default {};

	// 可与name组合使用,比较获取到的属性值与havingValue给定的值是否相同,相同才加载配置
	String havingValue() default "";

	// 缺少该配置属性时是否可以加载。如果为true,没有该配置属性时也会正常加载;反之则不会生效
	boolean matchIfMissing() default false;

}

其中在历史版本中还存在一个relaxedNames属性:

//是否可以松散匹配
boolean relaxedNames() default true;

最新版本中已经不存在该属性了。

通过注解ConditionalOnProperty上的@Conditional(OnPropertyCondition.class)代码,可以看出ConditionalOnProperty属于@Conditional的衍生注解。生效条件由OnPropertyCondition来进行判断。

使用方法

关于@ConditionalOnProperty的使用方法,我们在上面的Spring Boot中的使用已经看到。

@ConditionalOnProperty的核心功能是通过属性name以及havingValue来实现的。

首先看matchIfMissing属性,用来指定如果配置文件中未进行对应属性配置时的默认处理:默认情况下matchIfMissing为false,也就是说如果未进行属性配置,则自动配置不生效。如果matchIfMissing为true,则表示如果没有对应的属性配置,则自动配置默认生效。

下面看name属性,name用来从application.properties中读取某个属性值。比如上面Tomcat的自动配置在配置文件为:

spring.datasource.type=org.apache.tomcat.jdbc.pool.DataSource

在matchIfMissing为false时,如果name值为空,则返回false;如果name不为空,则将该值与havingValue指定的值进行比较,如果一样则返回true,否则返回false。返回false也就意味着自动配置不会生效。

但是如果看HttpEncodingAutoConfiguration类上的属性配置发现并没有完全按照上面所说的name和havingValue配合使用。它是通过“prefix+value”作为属性的名称来进行配置:

spring.http.encoding.enabled=true

其中prefix指定了配置的统一前缀“spring.http.encoding”,而value指定了具体的属性名称为“enabled”。这里并没有设置havingValue的值,如果havingValue未指定值,默认情况下在属性配置中设置的值为true则生效(如上配置),false则不生效。

原文链接:《SPRING BOOT中@CONDITIONALONPROPERTY使用详解


程序新视界:精彩和成长都不容错过
![程序新视界-微信公众号](https://img2018.cnblogs.com/blog/1742867/201910/1742867-20191013111755842-2090947098.png)

免责声明:文章转载自《Spring Boot中@ConditionalOnProperty使用详解》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇位图Vue在ASP.NET MVC中的进行前后端的交互下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Spring Boot常见问题(二)Unable to start embedded container; nested exception is java.lang.NoSuchMethodError: org.apache.tomcat.util.scan.StandardJarScanner.setJarScanFilter(Lorg/apache/tomcat/JarScanFilter;

问题描述:通过Spring Boot官方提供的方式,写出如下HelloWorld代码。 @Controller @EnableAutoConfiguration public class HelloWorld { @RequestMapping("/wu") @ResponseBody String home() {...

解决spring-boot-maven-plugin插件打包,springboot启动时报找不到主main问题

一:遇到的问题及解决方法 最近在搭建一个新项目时,使用spring-boot-maven-plugin插件打包,springboot项目在发布后启动时遇到找不到主main问题。 遇到这个问题当时感觉本地直接idea里启动springboot好好的,为什么用自动化发布工具发布后怎么就出现这个问题了呢? 就到线上打好的包解压看MANIFEST.MF文件里的内容...

更新Mac双系统多分区

前言制作Mac USB系统安装盘安装Mac OS 10.12制作win10 USB系统安装盘安装win10windows多分区实现 前言 同事有一台mac pro,系统是mac os 10.9+win7,由于办公比较多,所以一直使用win7,macos也就没有怎么升级,也没怎么用,后面买了个显示器,接入之后,发现win7的扩展显示器兼容性有问题,m...

如何在win7下通过easyBCD引导安装Ubuntu14.04

不需要U盘 在Win7下装Ubuntu双系统 本文测试安装的是32位的ubuntu-14.10-desktop-i386.iso 系统。 准备: Ubuntu系统ISO文件。EasyBCD 软件。  Step 1. 在windows里面把空余空间腾出来 计算机右键,管理,磁盘管理,通过压缩卷等方法得到要分给 Ubuntu系统的分区。或者原来你就有某个盘用于...

Android Fastboot 与 Recovery 和刷机 千山万水迷了鹿

1. 首先来看下Android系统的分区:   Android系统的分区.jpg   Android分区解释.png 安卓系统一般把rom芯片分成7个区,如果再加上内置sd卡这个分区,就是8个: hboot分区----------负责启动。 radio分区----------负责驱动。 recovery分区-------负责恢复。...

CentOS7.2 设置GRUB2引导界面分辨率

最近在学习OS引导启动,GRUB2的学习材料也不少,主要还看官方手册清晰些。 公司里办公机的多启动用的ubuntu的界面,还挺炫酷的。之前看其他博客网文里看到可以设置grub2的分辨率,我拿CentOS7.2试了下,发现不行。 网上都是说设置GRUB_GFXMODE=1440x900,再update-grub更新下grub.cfg,但是没生效(我又拿ubu...