Spring ConfigurationCondition接口详解

ConfigurationCondition:判断带有@Configuration注解的配置Class是否满足condition条件

所以这2个阶段的枚举的含义也就很明确了:

PARSE_CONFIGURATION:判断是否在解析配置类的时候就进行 condition 条件判断,若失败,则该配置类不注册

REGISTER_BEAN:所有配置类均注册为Bean

默认情况下,带有@Configuration注解的类  为full conguration , phase 为 PARSE_CONFIGURATION,其余方法带有@Bean,或者注解元数据中 带有 @Component,@ComponentScan,@Import,@ImportResource的 为 lite 模式,phase 为REGISTER_BEAN

前言:
最近在看@ConditionalOnBean的时候,看到了ConfigurationCondition接口,对这个接口比较陌生,故了解一下。

介绍:
ConfigurationCondition的定义是这样的,它继承了Condition类,如果读者对Condition类不不熟悉,可以在Spring @Conditional注解 详细讲解及示例 中了解。

package org.springframework.context.annotation;
 
public interface ConfigurationCondition extends Condition {
    ConfigurationCondition.ConfigurationPhase getConfigurationPhase();
 
    //可以翻译为构建阶段
    public static enum ConfigurationPhase {
        
        PARSE_CONFIGURATION,
        
        REGISTER_BEAN;
 
        private ConfigurationPhase() {
        }
    }
}


接口中有一个getConfigurationPhase方法,用来返回ConfigurationPhase枚举类型。

先来看看ConfigurationPhase枚举类型:

官方文档中对它的定义:

        The various configuration phases where the condition could be evaluated. 

        可以评估条件的各种配置阶段。

它有两个值:

PARSE_CONFIGURATION:

        Condition应评估@Configuration类,如果此时条件不匹配,@Configuration 则不会添加该类。

REGISTER_BEAN:

        该条件不会阻止 @Configuration添加类,在评估条件时,所有@Configurations都将被解析。

Stephane Nicoll在stackoverflow上说到:

ConfigurationCondition is a specialization of Condition for @Configuration classes.
    Plain Condition is just fine for 99% of your use cases so you should consider that first. The specialization is really about determining in which phase of the processing of @Configuration classes the condition should be evaluated.
    There are two phases:
        PARSE_CONFIGURATION evaluates the condition when the @Configuration-annotated class is parsed. This gives a chance to fully exclude the configuration class
        REGISTER_BEAN evaluates the condition when a bean from a configuration class is registered. This does not prevent the configuration class to be added but it allows to skip a bean definition if the condition does not match (as defined by the matches method of the Condition interface)
    Spring Boot has a OnBeanCondition that basically checks during the registration phase if another bean is present. This is the core of ConditionalOnBean that basically does something when a bean is present
ConfigurationCondition是一个专业化Condition的@Configuration类。    


    Condition对于99%的用例都很好,所以应该考虑一下。专业化实际上是关于确定应该评估条件的类处理的哪个阶段@Configuration。
    有两个阶段:

  • PARSE_CONFIGURATION:在@Configuration解析-annotated类时评估条件。这样就有机会完全排除配置类
  • REGISTER_BEAN:评估配置类中的bean注册时的条件。这不会阻止添加配置类,但如果条件不匹配(由Condition的matches方法定义),则允许跳过bean定义Condition

    Spring Boot OnBeanCondition在注册阶段基本上会检查是否存在另一个bean。这是ConditionalOnBean当bean存在时基本上做的事情的核心
实际在OnBeanCondition中的实现如下:    

/**
 * 将返回一个REGISTER_BEAN
*/
public ConfigurationPhase getConfigurationPhase() {
   return ConfigurationPhase.REGISTER_BEAN;
}


我的理解:
ConfigurationPhase的作用就是根据条件来判断是否加载这个配置类,OnBeanCondition(此注解的功能就是判断是否存在某个bean,如果存在,则不注入标注的bean或者类)之所以返回REGISTER_BEAN,是因为需要无论如何都要加载这个配置类(如果是PARSE_CONFIGURATION,则有可能不加载),配置类中的bean的注入需要再根据bean的注入条件来判断。

再者,@onBeanCondition的设计是想如果matches方法返回true,则注入bean,如果返回false则不注入bean。如果枚举值选择了PARSE_CONFIGURATION,matches返回false整个配置将不被加载了,和设计有冲突。
 

真·总结:
实验证明,ConfigurationPhase的作用并不是根据条件来判断是否加载这个配置类,实际ConfigurationPhase控制的是过滤的时机,是在创建Configuration类的时候过滤还是在创建bean的时候过滤(也可用条件注解的生效阶段来描述)。

参考链接:https://www.jianshu.com/p/c4df7be75d6e

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值