Spring ConfigurationCondition接口详解

前言:

最近在看@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

猜你喜欢

转载自blog.csdn.net/xcy1193068639/article/details/81589489