ConfigurationClassPostProcessor#processConfigBeanDefinitions执行流程

542 阅读2分钟

执行流程

创建容器new AnnotationConfigApplicationContext(AppConfig.class);

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
	//调用默认无参构造器,里面有一大堆初始化逻辑
	this();

	//把传入的Class进行注册,Class既可以有@Configuration注解,也可以没有@Configuration注解
	//怎么注册? 委托给了 org.springframework.context.annotation.AnnotatedBeanDefinitionReader.register 方法进行注册
	// 传入Class 生成  BeanDefinition , 然后通过 注册到 BeanDefinitionRegistry
	register(annotatedClasses);

	//刷新容器上下文
	refresh();
}

refresh();方法中,执行了invokeBeanFactoryPostProcessors(beanFactory);方法。

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
	// getBeanFactoryPostProcessors 获取的是 this.beanFactoryPostProcessors;
	//this.beanFactoryPostProcessors 只能通过 AbstractApplicationContext.addBeanFactoryPostProcessor 方法添加
	PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

	// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
	// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
	if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
		beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
		beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
	}
}

其中,最主要的是PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());。 在该方法中,第一次调用invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);时调用了ConfigurationClassPostProcessor#processConfigBeanDefinitions方法。

//ConfigurationClassPostProcessor#processConfigBeanDefinitions源码
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
	int registryId = System.identityHashCode(registry);
	if (this.registriesPostProcessed.contains(registryId)) {
		throw new IllegalStateException(
				"postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
	}
	if (this.factoriesPostProcessed.contains(registryId)) {
		throw new IllegalStateException(
				"postProcessBeanFactory already called on this post-processor against " + registry);
	}
	this.registriesPostProcessed.add(registryId);

	processConfigBeanDefinitions(registry);
}

做了两件事情:

  1. this.registriesPostProcessed.add(registryId);将id注册到registriesPostProcessed
  2. 调用processConfigBeanDefinitions(registry);方法,解析配置类。
//processConfigBeanDefinitions(registry)方法部分源码
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
    ...
    // 解析配置类
    parser.parse(candidates);
     ...
    Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
     ···
    // Import类,@Bean,@ImportResource 转化为 BeanDefinition
    this.reader.loadBeanDefinitions(configClasses);
     ...
}

parser.parse(candidates);源码:

public void parse(Set<BeanDefinitionHolder> configCandidates) {
	for (BeanDefinitionHolder holder : configCandidates) {
		BeanDefinition bd = holder.getBeanDefinition();
		try {
			// 根据不同的 BeanDefinition 实例对象 调用不同的 parse 方法
			// 底层其实都是在调用 org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass
			if (bd instanceof AnnotatedBeanDefinition) {
				parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
			} else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
				parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
			} else {
				parse(bd.getBeanClassName(), holder.getBeanName());
			}
		} catch (BeanDefinitionStoreException ex) {
			throw ex;
		} catch (Throwable ex) {
			throw new BeanDefinitionStoreException(
					"Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);
		}
	}
	//执行DeferredImportSelector
	this.deferredImportSelectorHandler.process();
}

parser.parse(candidates);负责解析配置类、解析非延迟加载的Import。 在解析配置类时,也维护了成员变量ConfigurationClassParser#configurationClasses。解析完配置类之后执行DeferredImportSelector(延迟加载大概就是在这里体现的)。

this.reader.loadBeanDefinitions(configClasses);负责将 Import类、@Bean、@ImportResource转化为BeanDefinition。configClasses参数来自ConfigurationClassParser#configurationClasses

Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());

public Set<ConfigurationClass> getConfigurationClasses() {
        // this.configurationClasses 为ConfigurationClassParser#configurationClasses
	return this.configurationClasses.keySet();
}

感谢关注微信公众号:

Corder小黑