Spring源码:ClassPathBeanDefinitionScanner源码分析

本文深入解析Spring框架中BeanDefinition的扫描与注册过程,重点介绍了ClassPathBeanDefinitionScanner和ClassPathScanningCandidateComponentProvider类的功能及其实现细节,包括TypeFilter、ConditionEvaluator和MetadataReaderFactory等关键组件的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

0. 前述

1.ClassPathScanningCandidateComponentProvider

1.1 TypeFilter

1.2 ConditionEvaluator

1.3 MetadataReaderFactory

2.ClassPathBeanDefinitionScanner

2.1 ScopeMetadataResolver

2.2 BeanNameGenerator

2.3 BeanDefinitionRegistry


0. 前述

ClassPathBeanDefinitionScanner的主要作用有两个:

  • 扫描类路径下的候选Component,构造BeanDefinition对象(实际为ScannedGenericBeanDefinition)
  • 利用BeanDefinitionRegister注册BeanDefinition到bean工厂中;

A bean definition scanner that detects bean candidates on the classpath,
registering corresponding bean definitions with a given registry ({@code BeanFactory} or {@code ApplicationContext}).

类图如下:

下面分别介绍下涉及的几个Class的作用

1.ClassPathScanningCandidateComponentProvider

ClassPathScanningCandidateComponentProvider是一个抽象类,实现EnvironmentCapable和ResourceLoaderAware接口,包含的主要成员变量有:ConditionEvaluator、ResourcePatternResolver、MetadataReaderFactory,同时依赖TypeFilter

/**
* A component provider that scans the classpath from a base package. It then
* applies exclude and include filters to the resulting classes to find candidates.
*
* <p>This implementation is based on Spring's
* {@link org.springframework.core.type.classreading.MetadataReader MetadataReader}
* facility, backed by an ASM {@link org.springframework.asm.ClassReader ClassReader}.

*/

1.1 TypeFilter

TypeFilter主要用于过滤满足条件的BeanDefinition

1.2 ConditionEvaluator

主要用于Conditional注解的处理,仅当条件满足时才会注册bean

1.3 MetadataReaderFactory

MetadataReaderFactory利用工厂方法模式提供创建MetadataReader的接口,实现类有SimpleMetadataReaderFactory、CachingMetadataReaderFactory

其中CachingMetadataReaderFactory提供了对每个.class 文件缓存MetadataReader实例;

Factory interface for {@link MetadataReader} instances.

Allows for caching a MetadataReader per original resource.

关联类图如下:

2.ClassPathBeanDefinitionScanner

ClassPathBeanDefinitionScanner主要干了两件事:

  1. 扫描类路径下的候选BeanDefinition

  2. 将BeanDefinition注册到BeanDefinitionRegister中

/**
* A bean definition scanner that detects bean candidates on the classpath,
* registering corresponding bean definitions with a given registry ({@code BeanFactory} or {@code ApplicationContext}).
*/

类图如下:

   /**
	 * Perform a scan within the specified base packages,
	 * returning the registered bean definitions.
	 * <p>This method does <i>not</i> register an annotation config processor
	 * but rather leaves this up to the caller.
	 * @param basePackages the packages to check for annotated classes
	 * @return set of beans registered if any for tooling registration purposes (never {@code null})
	 */
	protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
		Assert.notEmpty(basePackages, "At least one base package must be specified");
		Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<BeanDefinitionHolder>();
		for (String basePackage : basePackages) {
			Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
			for (BeanDefinition candidate : candidates) {
				ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
				candidate.setScope(scopeMetadata.getScopeName());
				String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
				if (candidate instanceof AbstractBeanDefinition) {
					postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
				}
				if (candidate instanceof AnnotatedBeanDefinition) {
					AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
				}
				if (checkCandidate(beanName, candidate)) {
					BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
					definitionHolder =
							AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
					beanDefinitions.add(definitionHolder);
					registerBeanDefinition(definitionHolder, this.registry);
				}
			}
		}
		return beanDefinitions;
    }

2.1 ScopeMetadataResolver

主要用于处理@Scope注解,提供获取ScopeMetaData对象的能力,并且基于代理模式创建代理类;

2.2 BeanNameGenerator

主要用于产生beanName

2.3 BeanDefinitionRegistry

注册BeanDefinition到容器中

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值