【SpringBoot】条件注解@Conditional

简概

https://docs.spring.io/spring-boot/docs/2.7.5/reference/htmlsingle/#features.developing-auto-configuration.condition-annotations

您几乎总是希望在自动配置类中包含一个或多个@Conditional注解。@ConditionalOnMissingBean注解是一个常见的例子,用于允许开发人员在不满意您的默认值时覆盖自动配置。

Spring Boot包含许多@Conditional注解,您可以在自己的代码(注解@Configuration的类或单独的@Bean方法)上重用这些注解。这些注解包括:

Class Conditions

@ConditionalOnClass@ConditionalOnMissingClass注解允许根据特定类的存在或不存在来决定是否包含@Configuration类。由于注解元数据是通过使用ASM解析的,所以可以使用value属性来引用真正的类,即使这个类实际上可能不会出现在正在运行的应用程序类路径上。如果您希望通过使用String值指定类名,也可以使用name属性。

这种机制并不以同样的方式应用于@Bean方法,在@Bean方法中,通常返回类型是条件的目标:在方法上的条件应用之前,JVM将加载类和潜在处理的方法引用,如果类不存在,这些方法引用将失败。【一个可参考点:https://cloud.tencent.com/developer/article/1449288

要处理这种情况,可以使用一个单独的@Configuration类来隔离条件,如下面的示例所示:

import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@AutoConfiguration
// Some conditions ...
public class MyAutoConfiguration {

    // Auto-configured beans ...

    @Configuration(proxyBeanMethods = false)
    @ConditionalOnClass(SomeService.class)
    public static class SomeServiceConfiguration {

        @Bean
        @ConditionalOnMissingBean
        public SomeService someService() {
            return new SomeService();
        }

    }
}

如果使用@ConditionalOnClass@ConditionalOnMissingClass作为元注解的一部分来组成自己的合成注解,在这种情况没有被处理时,必须使用name来引用类。

Bean Conditions

@ConditionalOnBean@ConditionalOnMissingBean注解允许根据特定bean的存在或不存在来决定是否包含bean。您可以使用value属性按type或name指定bean。search属性允许您限制在搜索bean时应该考虑的ApplicationContext层次结构。

当放在@Bean方法上时,目标类型默认为方法的返回类型,如下例所示:

import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;

@AutoConfiguration
public class MyAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public SomeService someService() {
        return new SomeService();
    }

}

在上面的示例中,如果ApplicationContext中没有包含someService类型的bean,则将创建someService bean。

需要特别注意添加bean定义的顺序,因为这些条件是根据到目前为止所处理的内容来计算的。由于这个原因,我们建议只在自动配置类上使用@ConditionalOnBean@ConditionalOnMissingBean注解(因为这能保证在添加任何用户定义的bean definitions后再加载这些注解)。

@ConditionalOnBean@ConditionalOnMissingBean不阻止@Configuration类的创建。在类级别使用这些条件与用注解标记其中包含的@Bean方法之间的唯一区别是,如果条件不匹配,前者会阻止将@Configuration类注册为bean

在声明@Bean方法时,在方法的返回类型中提供尽可能多的类型信息。例如,如果bean的具体类实现了一个接口,那么bean方法的返回类型应该是具体类而不是接口。在使用bean conditions时,在@Bean方法中提供尽可能多的类型信息尤其重要,因为它们的计算只能依赖于方法签名中可用的类型信息。

Property Conditions

@ConditionalOnProperty注解允许基于Spring Environment property来决定是否配置。使用前缀和名称属性指定应该检查的属性。缺省情况下,匹配任何存在且不等于false的属性。还可以通过使用havingValuematchIfMissing属性创建更高级的检查。

Web Application Conditions

@ConditionalOnWebApplication@ConditionalOnNotWebApplication注解允许根据应用程序是否是一个“web application”来决定是否配置。基于servlet的web应用程序是任何使用Spring WebApplicationContext、定义了session scope或具有ConfigurableWebEnvironment的应用程序。响应式web应用程序是任何使用ReactiveWebApplicationContextConfigurableReactiveWebEnvironment的应用程序。

@ConditionalOnWarDeployment注解允许根据应用程序是否是部署到容器的传统WAR应用程序来决定是否包含配置。此条件不适用于使用嵌入式服务器运行的应用程序。

SpEL Expression Conditions

@ConditionalOnExpression注解允许根据SpEL expression的结果决定是否包含配置。

在表达式中引用bean将导致在上下文刷新处理中很早就初始化该bean。因此,bean将不能进行后处理(例如配置属性绑定),并且它的状态可能是不完整的

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,084评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,623评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,450评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,322评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,370评论 6 390
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,274评论 1 300
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,126评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,980评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,414评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,599评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,773评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,470评论 5 344
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,080评论 3 327
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,713评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,852评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,865评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,689评论 2 354

推荐阅读更多精彩内容