Spring Conditional注解源码分析

入口

核心入口:使该注解生效的是一个 BeanFactoryPostProcessors 即 ConfigurationClassPostProcessor,在refresh方法流程中会被执行;

继承关系图(ConfigurationClassPostProcessor 实现了BeanDefinitionRegistryPostProcessor,BeanDefinitionRegistryPostProcessor继承了BeanFactoryPostProcessor)
在这里插入图片描述

后置处理器注入

那么 ConfigurationClassPostProcessor 这个类在什么时候注入的呢?
来看看这个类:org.springframework.context.config.ContextNamespaceHandler,熟悉Spring标签处理流程的应该能看懂;处理配置文件里标签的处理类都配置在了spring.handlers文件里,配置了schema和handler的映射关系;
我们来看看下面这个图片
在这里插入图片描述
进入这个标签集处理器,里面定义了具体标签的处理器

public class ContextNamespaceHandler extends NamespaceHandlerSupport {
    
    

	@Override
	public void init() {
    
    
		registerBeanDefinitionParser("property-placeholder", new PropertyPlaceholderBeanDefinitionParser());
		registerBeanDefinitionParser("property-override", new PropertyOverrideBeanDefinitionParser());
		registerBeanDefinitionParser("annotation-config", new AnnotationConfigBeanDefinitionParser());
		registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser());
		registerBeanDefinitionParser("load-time-weaver", new LoadTimeWeaverBeanDefinitionParser());
		registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
		registerBeanDefinitionParser("mbean-export", new MBeanExportBeanDefinitionParser());
		registerBeanDefinitionParser("mbean-server", new MBeanServerBeanDefinitionParser());
	}

}

下面我们关键看两个标签 “annotation-config”,"component-scan"的处理逻辑(省略):AnnotationConfigBeanDefinitionParser和
ComponentScanBeanDefinitionParser两个类里都会向容器注入 ConfigurationClassPostProcessor 工厂后置处理器,具体代码:

if (annotationConfig) {
    
    
			Set<BeanDefinitionHolder> processorDefinitions =
					AnnotationConfigUtils.registerAnnotationConfigProcessors(readerContext.getRegistry(), source);
			for (BeanDefinitionHolder processorDefinition : processorDefinitions) {
    
    
				compositeDef.addNestedComponent(new BeanComponentDefinition(processorDefinition));
			}
		}

然后再看看 org.springframework.context.annotation.AnnotationConfigUtils#registerAnnotationConfigProcessors(org.springframework.beans.factory.support.BeanDefinitionRegistry, java.lang.Object)方法

		if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
    
    
			RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

Condition流程

下图是方法调用的调用堆栈,我一般喜欢这样看,这样比较清楚入口和调用时机
在这里插入图片描述
下面来到核心方法

org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsForBeanMethod
|
org.springframework.context.annotation.ConditionEvaluator#shouldSkip(org.springframework.core.type.AnnotatedTypeMetadata, org.springframework.context.annotation.ConfigurationCondition.ConfigurationPhase)

猜你喜欢

转载自blog.csdn.net/Aqu415/article/details/115415977