Spring refresh - invokeBeanFactoryPostProcessors

博文目录


方法说明

BeanFactoryPostProcessors 和 BeanDefinitionRegistryPostProcessor 主要的功能就是 注册和修改 BeanDefinition

本方法将自动或手动注册的各种 BeanFactoryPostProcessors (包括 BeanDefinitionRegistryPostProcessor) 按一定的顺序逐个调用其 postProcessBeanDefinitionRegistry 和 postProcessBeanFactory 方法. 注意会优先调用 getBean 来实例化实现了 BeanFactoryPostProcessor 的组件

当前阶段满足条件的只有解析配置类的配置类后置处理器 ConfigurationClassPostProcessor, 所以 invokeBeanFactoryPostProcessors 方法可以认为就是在解析配置类

ConfigurationClassPostProcessor 是配置类后置处理器, 主要是从当前阶段的所有 BeanDefinition 中找到配置类, 然后交由 ConfigurationClassParser 来解析这个配置类, 将相关的候选组件全都注册成为 BeanDefinition. 最后给加了 @Configuration 注解的配置类做 CGLib 动态代理

ConfigurationClassPostProcessor 的 postProcessBeanDefinitionRegistry 方法, 会从当前已注册的 BeanDefinition 中找到配置类, 把配置类本身, 配置类上面的 @PropertySource, @ComponentScan, @Import, @ImportResource 等注解或配置类中被 @Bean 注解标注的方法都解析出来, 生成对应的 BeanDefinition 并注册到容器中

如何判断一个 BeanDefinition 是一个配置类? ConfigurationClassUtils.checkConfigurationClassCandidate

  • 有 @Configuration注解的 BeanDefinition, 标记为 FULL 配置类
  • 没有 @Configuration 注解, 但是有 @Component, @ComponentScan, @Import, @ImportResource 注解中任意一个, 或者类中有 @Bean 注解标注的方法的 BeanDefinition, 标记为 LITE 配置类

解析 @ComponentScan 的时候会扫描其指定的 basePackages 路径, 将标注有 @Component (@Repository, @Service, @Controller, @RestController 等含有 @Component 元注解, 也会被扫描到), @ManagedBean, @Named 注解的类也解析到

解析 @Import 的时候,

解析 @ImportResource 的时候,

解析 @Bean 的时候,

AbstractApplicationContext#invokeBeanFactoryPostProcessors

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {

	// 返回 AbstractApplicationContext 的 beanFactoryPostProcessors
	// 这个里面存的是通过 applicationContext.addBeanFactoryPostProcessor 添加进来的 BeanFactoryPostProcessor, 没有添加的话就是空的
	// 创世纪后置处理器都是从 BeanDefinitionMap 中根据类型找出来的
	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

要先搞清楚 BeanDefinitionRegistryPostProcessor 和 BeanFactoryPostProcessor 的关系, 两者都是接口, 前者继承了后者, 后者有 postProcessBeanFactory 方法, 前者继承了该方法, 同时还扩展了postProcessBeanDefinitionRegistry 方法

BeanDefinitionRegistryPostProcessor 一定是 BeanFactoryPostProcessor, 但 BeanFactoryPostProcessor 不一定是 BeanDefinitionRegistryPostProcessor

interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor

BeanFactoryPostProcessor 的执行顺序

BeanFactoryPostProcessor 的执行顺序, 分两步, 先走 BeanDefinitionRegistryPostProcessor 的 postProcessBeanDefinitionRegistry 方法 和 postProcessBeanFactory 方法, 再走 BeanFactoryPostProcessor (非 BeanDefinitionRegistryPostProcessor) 的 postProcessBeanFactory 方法, 具体流程如下

先判断 refresh 中的 obtainFreshBeanFactory() 拿到的 BeanFactory 是不是一个 BeanDefinitionRegistry. 这里拿到的是 GenericApplicationContext 的 beanFactory 属性, 即 DefaultListableBeanFactory, 实现了 BeanDefinitionRegistry

  • 传入的 beanFactory 是 BeanDefinitionRegistry

    • 先检查手动注册的 beanFactoryPostProcessors, 按照是否实现了 BeanDefinitionRegistryPostProcessor 分成两组, 实现了的调用其 postProcessBeanDefinitionRegistry
    • 找到自动注册的且实现了优先排序接口的 BeanDefinitionRegistryPostProcessor (仅实现了 BeanFactoryPostProcessor 而没有实现 BeanDefinitionRegistryPostProcessor 的不会被找出来), 提前执行 getBean, 逐个调用 postProcessBeanDefinitionRegistry 方法. ConfigurationClassPostProcessor 的 postProcessBeanDefinitionRegistry 方法就是在这里调用的
    • 找到自动注册的且实现了排序接口的 BeanDefinitionRegistryPostProcessor (实现了优先排序接口的也会被找出来, 但是会在遍历时排除), 逐个调用 postProcessBeanDefinitionRegistry 方法
    • 找到自动注册的剩余未处理的 BeanDefinitionRegistryPostProcessor (实现了优先排序接口和排序接口的也会被找出来, 但是会在遍历时排除), 逐个调用 postProcessBeanDefinitionRegistry 方法
    • 调用所有手动或自动注册的 BeanDefinitionRegistryPostProcessor 的 postProcessBeanFactory 方法. ConfigurationClassPostProcessor 的 postProcessBeanFactory 方法就是在这里调用的
    • 调用所有手动注册的 BeanFactoryPostProcessor (非 BeanDefinitionRegistryPostProcessor) 的 postProcessBeanFactory 方法
  • 传入的 beanFactory 不是 BeanDefinitionRegistry

    • 调用手动注册的 BeanFactoryPostProcessor (不管是不是 BeanDefinitionRegistryPostProcessor) 的 postProcessBeanFactory 方法
  • 找到所有自动注册的 BeanFactoryPostProcessor (含有 BeanDefinitionRegistryPostProcessor, 通过 contains 过滤), 按照是否实现了优先排序接口, 是否实现了排序接口, 没实现排序接口 分成3组, 按顺序调用其 postProcessBeanFactory 方法

BeanFactoryPostProcessor 详细流程说明

// 要先搞清楚 BeanDefinitionRegistryPostProcessor 和 BeanFactoryPostProcessor 的关系,
// 两者都是接口, 前者继承了后者, 后者有 postProcessBeanFactory 方法, 前者继承了该方法, 同时还扩展了postProcessBeanDefinitionRegistry 方法
// BeanDefinitionRegistryPostProcessor 一定是 BeanFactoryPostProcessor, 但 BeanFactoryPostProcessor 不一定是 BeanDefinitionRegistryPostProcessor

// BeanFactoryPostProcessor 的执行顺序, 分两步, 
// 先走 BeanDefinitionRegistryPostProcessor 的 postProcessBeanDefinitionRegistry 方法 和 postProcessBeanFactory 方法, 
// 再走 BeanFactoryPostProcessor (非 BeanDefinitionRegistryPostProcessor) 的 postProcessBeanFactory 方法
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

	// Invoke BeanDefinitionRegistryPostProcessors first, if any.
	// 已经处理过的 BeanFactoryPostProcessor 实例保存在这里, 通过判断这里面有没有, 就知道有没有调用过
	Set<String> processedBeans = new HashSet<>();

	// 因为是 DefaultListableBeanFactory, 所以也是 BeanDefinitionRegistry
	if (beanFactory instanceof BeanDefinitionRegistry) {
		BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;

		// 存的是手动注册的 BeanFactoryPostProcessor(非 BeanDefinitionRegistryPostProcessor)
		// BeanFactoryPostProcessor 里只有 postProcessBeanFactory 方法
		List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();

		// 存的是手动或自动注册的 BeanDefinitionRegistryPostProcessor
		// 因为 BeanDefinitionRegistryPostProcessor 继承了 BeanFactoryPostProcessor
		// 所以 BeanDefinitionRegistryPostProcessor 有 postProcessBeanDefinitionRegistry 和 postProcessBeanFactory 方法
		// 存的是已经调用过 postProcessBeanDefinitionRegistry 的 BeanDefinitionRegistryPostProcessor, 其 postProcessBeanFactory 还没有调用
		List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

		// 优先调用手动注册的 BeanDefinitionRegistryPostProcessor
		// 传进来的 beanFactoryPostProcessors 是手动添加的, 没有手动添加那就是空的
		for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {

			// 如果是 BeanDefinitionRegistryPostProcessor, 调用 postProcessBeanDefinitionRegistry
			if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
				BeanDefinitionRegistryPostProcessor registryProcessor =
						(BeanDefinitionRegistryPostProcessor) postProcessor;
				registryProcessor.postProcessBeanDefinitionRegistry(registry);
				registryProcessors.add(registryProcessor);
			}
			else {

				// 不是 BeanDefinitionRegistryPostProcessor 的, 添加到 regularPostProcessors
				regularPostProcessors.add(postProcessor);
			}
		}

		// Do not initialize FactoryBeans here: We need to leave all regular beans
		// uninitialized to let the bean factory post-processors apply to them!
		// Separate between BeanDefinitionRegistryPostProcessors that implement
		// PriorityOrdered, Ordered, and the rest.

		// 保存当前马上就要被调用方法的 BeanFactoryPostProcessor 的实例
		List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

		// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
		// 接下来调用自动注册的且实现了优先排序接口的 BeanDefinitionRegistryPostProcessor, ConfigurationClassPostProcessor 就是在这里调用的
		// 先从 BeanDefinitionMap 中找到所有 BeanDefinitionRegistryPostProcessor 类型的 BeanDefinition, 然后 getBean 创建, 添加到临时容器, 统一调用, 清空临时容器
		// 如果是通过 ConfigurationClassPostProcessor 扫描出来的自定义的 BeanDefinitionRegistryPostProcessor, 
		// 会在 ConfigurationClassPostProcessor 的 postProcessBeanDefinitionRegistry 方法中被注册成为 BeanDefinition
		// 然后在下一波(实现了优先排序或排序接口)或下下波(没有实现排序接口)查找时找到并执行 postProcessBeanDefinitionRegistry 方法
		// 在 invokeBeanFactoryPostProcessors(registryProcessors, beanFactory); 执行 postProcessBeanFactory 方法
		String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
		for (String ppName : postProcessorNames) {
			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
				currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
				processedBeans.add(ppName);
			}
		}
		sortPostProcessors(currentRegistryProcessors, beanFactory);
		registryProcessors.addAll(currentRegistryProcessors);
		// 逐个调用 postProcessBeanDefinitionRegistry 方法
		// 其实是调用 ConfigurationClassPostProcessor 的 postProcessBeanDefinitionRegistry 方法
		invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
		currentRegistryProcessors.clear();

		// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
		// 接下来调用自动注册的且实现了排序接口的 BeanDefinitionRegistryPostProcessor, 实现了优先排序接口的还会被找出来, 通过 contains 排除
		postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
		for (String ppName : postProcessorNames) {
			if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
				currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
				processedBeans.add(ppName);
			}
		}
		sortPostProcessors(currentRegistryProcessors, beanFactory);
		registryProcessors.addAll(currentRegistryProcessors);
		invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
		currentRegistryProcessors.clear();

		// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
		// 接下来调用自动注册的剩余的 BeanDefinitionRegistryPostProcessor, 实现了排序接口的还会被找出来, 通过 contains 排除
		boolean reiterate = true;
		while (reiterate) {
			reiterate = false;
			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
				if (!processedBeans.contains(ppName)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
					processedBeans.add(ppName);
					reiterate = true;
				}
			}
			sortPostProcessors(currentRegistryProcessors, beanFactory);
			registryProcessors.addAll(currentRegistryProcessors);
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
			currentRegistryProcessors.clear();
		}

		// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
		// 调用所有手动或自动注册的 BeanDefinitionRegistryPostProcessor 的 postProcessBeanFactory 方法
		// 其实是调用 ConfigurationClassPostProcessor 的 postProcessBeanFactory 方法
		invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
		// 调用所有手动注册的 BeanFactoryPostProcessor(非 BeanDefinitionRegistryPostProcessor) 的 postProcessBeanFactory 方法
		invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
	}

	else {
		// Invoke factory processors registered with the context instance.
		// 调用手动注册的 BeanFactoryPostProcessor 的 postProcessBeanFactory 方法
		invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
	}

	// Do not initialize FactoryBeans here: We need to leave all regular beans
	// uninitialized to let the bean factory post-processors apply to them!

	// 先从 BeanDefinitionMap 中找到所有 BeanFactoryPostProcessor 类型的 BeanDefinition
	// BeanDefinitionRegistryPostProcessor 的也会被找出来, 通过 contains 来判断是否处理过
	// 创世纪的 ConfigurationClassPostProcessor 和 EventListenerMethodProcessor 都会被找出来
	String[] postProcessorNames =
			beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

	// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
	// Ordered, and the rest.
	// 有优先排序接口的
	List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
	// 有排序接口的
	List<String> orderedPostProcessorNames = new ArrayList<>();
	// 没有排序接口的
	List<String> nonOrderedPostProcessorNames = new ArrayList<>();
	for (String ppName : postProcessorNames) {
		if (processedBeans.contains(ppName)) {
			// skip - already processed in first phase above
		}
		else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
			priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
		}
		else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
			orderedPostProcessorNames.add(ppName);
		}
		else {
			nonOrderedPostProcessorNames.add(ppName);
		}
	}

	// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
	sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
	// 调用仅实现了 BeanFactoryPostProcessors 和 优先排序接口的后置处理器的 postProcessBeanFactory 方法
	invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

	// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
	List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
	for (String postProcessorName : orderedPostProcessorNames) {
		orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
	}
	sortPostProcessors(orderedPostProcessors, beanFactory);
	// 调用仅实现了 BeanFactoryPostProcessors 和 排序接口的后置处理器的 postProcessBeanFactory 方法
	invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

	// Finally, invoke all other BeanFactoryPostProcessors.
	List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
	for (String postProcessorName : nonOrderedPostProcessorNames) {
		nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
	}
	// 调用仅实现了 BeanFactoryPostProcessors 的后置处理器的 postProcessBeanFactory 方法
	invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

	// Clear cached merged bean definitions since the post-processors might have
	// modified the original metadata, e.g. replacing placeholders in values...
	beanFactory.clearMetadataCache();
}

ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry

public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
	
	// ...

	// 解析 配置类, 如果没有注册配置类, 则流程会在检测是否有配置类后中断
	// 解析 @PropertySource, @ComponentScan, @Import, @ImportSelector, @Bean, 将相关类注册成为 BeanDefinition
	processConfigBeanDefinitions(registry);
}

ConfigurationClassPostProcessor#processConfigBeanDefinitions

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
		List<BeanDefinitionHolder> configCandidates = new ArrayList<>();

	// 获取到目前所有已注册的 BeanDefinition 的名字, 从里面找到 配置类 候选
	String[] candidateNames = registry.getBeanDefinitionNames();

	for (String beanName : candidateNames) {
		BeanDefinition beanDef = registry.getBeanDefinition(beanName);

		// 如果 BeanDefinition 存在 ConfigurationClassPostProcessor.configurationClass 属性, 说明该 BeanDefinition 已经被作为一个配置类解析过了
		if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
			if (logger.isDebugEnabled()) {
				logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
			}
		}

		// 不存在 ConfigurationClassPostProcessor.configurationClass 属性, 但是符合配置类候选的条件, 添加到 configCandidates 中
		// 符合的条件有如下两个
		// 有 @Configuration注解, 标记为 FULL 配置类
		// 没有 @Configuration 注解, 但是存在 @Component, @ComponentScan, @Import, @ImportResource, 或者类中有 @Bean 注解标注的方法, 标记为 LITE 配置类
		else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
			
			// 找到的候选就添加到 configCandidates 中
			configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
		}
	}

	// Return immediately if no @Configuration classes were found
	// 没有找到符合配置类条件的候选项, 解析配置类流程终止
	if (configCandidates.isEmpty()) {
		return;
	}

	// Sort by previously determined @Order value, if applicable
	// 多个配置类候选的话需要排序
	configCandidates.sort((bd1, bd2) -> {
		int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
		int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
		return Integer.compare(i1, i2);
	});

	// ...

	// Parse each @Configuration class
	// 创建了一个配置类解析器对象
	ConfigurationClassParser parser = new ConfigurationClassParser(
			this.metadataReaderFactory, this.problemReporter, this.environment,
			this.resourceLoader, this.componentScanBeanNameGenerator, registry);

	Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
	Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
	do {

		// 开始解析配置类
		// 逐个解析配置类的 @PropertySource, @ComponentScan, @Import, @ImportResource, @Bean 方法
		// @ComponentScan 扫描 basePackages, 扫描到的组件会注册成为 BeanDefinition, 如果是配置类则递归解析
		// @Import 导入的类会分成3种,
		// 		ImportSelector 中延迟的被暂存起来, 非延迟的被递归解析,
		// 		ImportBeanDefinitionRegistrar 的被暂存起来,
		// 		都不是的会被当做配置类走配置类解析流程
		// @ImportResource 导入的 xml 也被暂存起来
		// @Bean 注解的方法也被暂存起来
		parser.parse(candidates);
		parser.validate();

		// 将上述暂存起来的都统一处理
		// 取到 parser 里面解析过的配置类
		Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
		configClasses.removeAll(alreadyParsed);

		// Read the model and create bean definitions based on its content
		if (this.reader == null) {
			this.reader = new ConfigurationClassBeanDefinitionReader(
					registry, this.sourceExtractor, this.resourceLoader, this.environment,
					this.importBeanNameGenerator, parser.getImportRegistry());
		}
		
		// 用一个 reader 从被解析过的配置类中读取并注册 BeanDefinition
		this.reader.loadBeanDefinitions(configClasses);
		alreadyParsed.addAll(configClasses);

		candidates.clear();
		if (registry.getBeanDefinitionCount() > candidateNames.length) {
			String[] newCandidateNames = registry.getBeanDefinitionNames();
			Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
			Set<String> alreadyParsedClasses = new HashSet<>();
			for (ConfigurationClass configurationClass : alreadyParsed) {
				alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
			}
			for (String candidateName : newCandidateNames) {
				if (!oldCandidateNames.contains(candidateName)) {
					BeanDefinition bd = registry.getBeanDefinition(candidateName);
					if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
							!alreadyParsedClasses.contains(bd.getBeanClassName())) {
						candidates.add(new BeanDefinitionHolder(bd, candidateName));
					}
				}
			}
			candidateNames = newCandidateNames;
		}
	}
	while (!candidates.isEmpty());

	// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
	if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
		sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
	}

	if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
		// Clear cache in externally provided MetadataReaderFactory; this is a no-op
		// for a shared cache since it'll be cleared by the ApplicationContext.
		((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
	}
}

如何确定一个类是否为配置类

  • 判断 BeanDefinition 中是否有 ConfigurationClassPostProcessor.configurationClass 属性, 有就说明是配置类, 该属性在首次判断的时候添加的
  • 不存在 ConfigurationClassPostProcessor.configurationClass 属性, 则需要重新判断一遍是否是配置类, 符合的条件有如下两个
    • 有 @Configuration注解, 标记为 FULL 配置类
    • 没有 @Configuration 注解, 但是存在 @Component, @ComponentScan, @Import, @ImportResource, 或者类中有 @Bean 注解标注的方法, 标记为 LITE 配置类

ConfigurationClassParser#parse(Set< BeanDefinitionHolder>)

public void parse(Set<BeanDefinitionHolder> configCandidates) {
	for (BeanDefinitionHolder holder : configCandidates) {
		BeanDefinition bd = holder.getBeanDefinition();
		try {
			// 通过 AnnotationConfigApplicationContext 传入的配置类被封装为 AnnotatedGenericBeanDefinition
			// class AnnotatedGenericBeanDefinition extends GenericBeanDefinition implements AnnotatedBeanDefinition
			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);
		}
	}

	this.deferredImportSelectorHandler.process();
}

ConfigurationClassParser#parse(AnnotationMetadata, String)

protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {

	// 把配置类元信息和 BeanName 包装成一个 ConfigurationClass 对象
	// DEFAULT_EXCLUSION_FILTER: 某类名满足以 java.lang.annotation. 和 org.springframework.stereotype. 开头的
	processConfigurationClass(new ConfigurationClass(metadata, beanName), DEFAULT_EXCLUSION_FILTER);
}

ConfigurationClassParser#processConfigurationClass

protected void processConfigurationClass(ConfigurationClass configClass, Predicate<String> filter) throws IOException {
	if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
		return;
	}

	ConfigurationClass existingClass = this.configurationClasses.get(configClass);
	if (existingClass != null) {
		// 传入的配置类是通过其他配置类的 @Import 导入进来的
		if (configClass.isImported()) {
			if (existingClass.isImported()) {
				// 需要合并配置
				existingClass.mergeImportedBy(configClass);
			}
			// Otherwise ignore new imported config class; existing non-imported class overrides it.
			return;
		}
		else {
			// Explicit bean definition found, probably replacing an import.
			// Let's remove the old one and go with the new one.
			this.configurationClasses.remove(configClass);
			this.knownSuperclasses.values().removeIf(configClass::equals);
		}
	}

	// Recursively process the configuration class and its superclass hierarchy.
	SourceClass sourceClass = asSourceClass(configClass, filter);
	do {

		// 真正开始解析配置类的入口
		// 会解析 @PropertySource, @ComponentScan, @Import, @ImportResource, @Bean 等
		sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter);
	}
	while (sourceClass != null);

	this.configurationClasses.put(configClass, configClass);
}

ConfigurationClassParser#doProcessConfigurationClass

protected final SourceClass doProcessConfigurationClass(
			ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)
			throws IOException {

	// @Configuration 注解内有元注解 @Component
	if (configClass.getMetadata().isAnnotated(Component.class.getName())) {

		// Recursively process any member (nested) classes first
		// ?
		processMemberClasses(configClass, sourceClass, filter);
	}

	// Process any @PropertySource annotations
	// 处理 @PropertySource 注解
	// @PropertySources 是容器类注解, value 里面可以放多个 @PropertySource 注解
	// 把元信息中的 @PropertySource 和 @PropertySources 中的 @PropertySource 都拿到, 然后一个一个的解析
	for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
			sourceClass.getMetadata(), PropertySources.class,
			org.springframework.context.annotation.PropertySource.class)) {
		if (this.environment instanceof ConfigurableEnvironment) {
			processPropertySource(propertySource);
		}
		else {
			logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
					"]. Reason: Environment must implement ConfigurableEnvironment");
		}
	}

	// Process any @ComponentScan annotations
	// 处理 @ComponentScan 注解
	// @ComponentScans 是容器类注解, value 里面可以放多个 @ComponentScan 注解
	// 把元信息中的 @ComponentScan 和 @ComponentScans 中的 @ComponentScan 都拿到, 然后一个一个的解析
	Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
			sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
	if (!componentScans.isEmpty() &&
			!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
		for (AnnotationAttributes componentScan : componentScans) {

			// The config class is annotated with @ComponentScan -> perform the scan immediately
			// 通过 ComponentScanAnnotationParser 实例来解析每一个 @ComponentScan
			Set<BeanDefinitionHolder> scannedBeanDefinitions =
					this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
			// Check the set of scanned definitions for any further config classes and parse recursively if needed
			for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
				BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
				if (bdCand == null) {
					bdCand = holder.getBeanDefinition();
				}
				// 如果解析出来的配置类仍然是一个配置类, 继续递归解析
				if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
					parse(bdCand.getBeanClassName(), holder.getBeanName());
				}
			}
		}
	}

	// Process any @Import annotations
	// 处理 @Import 注解
	processImports(configClass, sourceClass, getImports(sourceClass), filter, true);

	// Process any @ImportResource annotations
	// 处理 @ImportResource 注解
	AnnotationAttributes importResource =
			AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
	if (importResource != null) {
		String[] resources = importResource.getStringArray("locations");
		Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
		for (String resource : resources) {
			String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
			configClass.addImportedResource(resolvedResource, readerClass);
		}
	}

	// Process individual @Bean methods
	// 处理 @Bean 注解标注的方法
	Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
	for (MethodMetadata methodMetadata : beanMethods) {
		configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
	}

	// Process default methods on interfaces
	// /
	processInterfaces(configClass, sourceClass);

	// Process superclass, if any
	// 处理父类?
	if (sourceClass.getMetadata().hasSuperClass()) {
		String superclass = sourceClass.getMetadata().getSuperClassName();
		if (superclass != null && !superclass.startsWith("java") &&
				!this.knownSuperclasses.containsKey(superclass)) {
			this.knownSuperclasses.put(superclass, configClass);
			// Superclass found, return its annotation metadata and recurse
			return sourceClass.getSuperClass();
		}
	}

	// No superclass -> processing is complete
	return null;
}

解析 @ComponentScan

Spring refresh - invokeBeanFactoryPostProcessors - 解析 @ComponentScan

解析 @Import

Spring refresh - invokeBeanFactoryPostProcessors - 解析 @Import

解析 @Bean 方法

Spring refresh - invokeBeanFactoryPostProcessors - 解析 @Bean

相同 BeanName 的处理

同一个 ClassPathBeanDefinitionScanner 里面扫描出来的多个相同 BeanName 会报错, 假如一个是通过 ClassPathBeanDefinitionScanner 扫描出来的, 一个是通过 @Bean 创建出来的, 则后面的会覆盖掉前面的

不太确定对不对?

ConfigurationClassBeanDefinitionReader#loadBeanDefinitions

读取解析并暂存到配置类容器 ConfigurationClass 中的数据, 最终注册成为 BeanDefinition

ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsForConfigurationClass

private void loadBeanDefinitionsForConfigurationClass(
			ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {

	// ...

	if (configClass.isImported()) {

		// 如果该配置类是被 @Import 导入进来的, 把该配置类先注册成为 BeanDefinition
		registerBeanDefinitionForImportedConfigurationClass(configClass);
	}
	for (BeanMethod beanMethod : configClass.getBeanMethods()) {

		// 将 @Bean 方法注册成为 BeanDefinition
		// 如果 @Bean 定义了 name, 则第一个作为 BeanName, 其他的作为 alias, 如果没有定义, BeanName 使用方法名字
		loadBeanDefinitionsForBeanMethod(beanMethod);
	}

	// 将 @ImportResource 导入的 xml 使用 XmlBeanDefinitionReader 解析并注册 BeanDefinition
	loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());

	// 将 @Import 导入的 ImportBeanDefinitionRegistrar 中要注册的 BeanDefinition 都注册好
	loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());

	// 还差延迟导入型选择器的解析

}

ConfigurationClassPostProcessor#postProcessBeanFactory

public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
	int factoryId = System.identityHashCode(beanFactory);
	if (this.factoriesPostProcessed.contains(factoryId)) {
		throw new IllegalStateException(
				"postProcessBeanFactory already called on this post-processor against " + beanFactory);
	}
	this.factoriesPostProcessed.add(factoryId);
	if (!this.registriesPostProcessed.contains(factoryId)) {
		// BeanDefinitionRegistryPostProcessor hook apparently not supported...
		// Simply call processConfigurationClasses lazily at this point then.
		processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
	}

	// 使用 CGLib 增强配置类
	// 加了 @Configuration 注解的配置类叫做 FULL 配置类, 没有的叫做 LITE 配置类, 在 BeanDefinition 中会有不同的标记
	// FULL 配置类中的 @Bean 方法如果调用其他加了 @Bean 注解的方法, 就会从容器中调用 getBean 来获取这个 Bean
	// LITE 配置类中则是没有动态代理, 可以直接多次调用 @Bean 注解的方法, 可能会产生多例
	enhanceConfigurationClasses(beanFactory);
	
	// 添加了 ImportAwareBeanPostProcessor
	// 干啥的还不清楚
	beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
}

配置类是否需要加 @Configuration

加 @Configuration 的配置类被 Spring 称为 Full, 反之称为 Lite, Full 的在解析时会做 CGLib 动态代理

配置类中的 @Bean 配置会受 @Configuration 有无的影响
没有 @Configuration 时, 在创建 Bean b 时, 会调用 b(), 在创建 Bean a 的时候还会再调用一次 b(), B 被实例化两次
配置 @Configuration 时, 调用 b() 会被 CGLib 动态代理加强, 会先从容器中获取, 有的话, 就不会再次调用了, 没有的话, 会创建并加入到容器中

@Bean
public B b() {
	return new B();
}
@Bean
public A a() {
	b();
	return new A();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值